Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/meta-flow.c | 122 ++++++++++++++++++++++++++---------------------- lib/meta-flow.h | 13 +++++- lib/nx-match.c | 125 ++++++++++++++++++++++++++++---------------------- lib/nx-match.h | 2 +- lib/ofp-actions.c | 7 +-- lib/ofp-util.c | 9 ++-- lib/ofp-util.h | 2 + tests/ovs-ofctl.at | 6 +-- utilities/ovs-ofctl.c | 26 +++++++---- 9 files changed, 178 insertions(+), 134 deletions(-)
diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 6ef564e..5803ded 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, 2013 Nicira, Inc. + * Copyright (c) 2011, 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, NXM_NX_DP_HASH, "NXM_NX_DP_HASH", - NXM_NX_DP_HASH, "NXM_NX_DP_HASH", + NXM_NX_DP_HASH, "NXM_NX_DP_HASH", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -71,7 +71,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID", - NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID", + NXM_NX_RECIRC_ID, "NXM_NX_RECIRC_ID", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -83,7 +83,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_NX_TUN_ID, "NXM_NX_TUN_ID", - OXM_OF_TUNNEL_ID, "OXM_OF_TUNNEL_ID", + OXM_OF_TUNNEL_ID, "OXM_OF_TUNNEL_ID", OFP13_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, FLOW_U32OFS(tunnel.tun_id), @@ -95,7 +95,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC", - NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC", + NXM_NX_TUN_IPV4_SRC, "NXM_NX_TUN_IPV4_SRC", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, FLOW_U32OFS(tunnel.ip_src), @@ -107,7 +107,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST", - NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST", + NXM_NX_TUN_IPV4_DST, "NXM_NX_TUN_IPV4_DST", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, FLOW_U32OFS(tunnel.ip_dst), @@ -119,7 +119,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_NONE, OFPUTIL_P_NONE, -1, @@ -131,7 +131,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_NONE, OFPUTIL_P_NONE, -1, @@ -143,7 +143,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_NONE, OFPUTIL_P_NONE, -1, @@ -155,7 +155,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, OXM_OF_METADATA, "OXM_OF_METADATA", - OXM_OF_METADATA, "OXM_OF_METADATA", + OXM_OF_METADATA, "OXM_OF_METADATA", OFP12_VERSION, OFPUTIL_P_NXM_OF11_UP, OFPUTIL_P_NXM_OF11_UP, -1, @@ -167,7 +167,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_OF_IN_PORT, "NXM_OF_IN_PORT", - NXM_OF_IN_PORT, "NXM_OF_IN_PORT", + NXM_OF_IN_PORT, "NXM_OF_IN_PORT", 0, OFPUTIL_P_ANY, /* OF11+ via mapping to 32 bits. */ OFPUTIL_P_NONE, -1, @@ -179,7 +179,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, OXM_OF_IN_PORT, "OXM_OF_IN_PORT", - OXM_OF_IN_PORT, "OXM_OF_IN_PORT", + OXM_OF_IN_PORT, "OXM_OF_IN_PORT", OFP12_VERSION, OFPUTIL_P_OF11_UP, OFPUTIL_P_NONE, -1, @@ -191,7 +191,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_NONE, OFPUTIL_P_NONE, -1, @@ -203,7 +203,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK", - NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK", + NXM_NX_PKT_MARK, "NXM_NX_PKT_MARK", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -218,7 +218,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, \ true, \ NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, \ - NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, \ + NXM_NX_REG(IDX), "NXM_NX_REG" #IDX, 0, \ OFPUTIL_P_NXM_OXM_ANY, \ OFPUTIL_P_NXM_OXM_ANY, \ -1, \ @@ -263,7 +263,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_OF_ETH_SRC, "NXM_OF_ETH_SRC", - OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC", + OXM_OF_ETH_SRC, "OXM_OF_ETH_SRC", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, /* Bitwise masking only with NXM and OF11+! */ -1, @@ -275,7 +275,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_OF_ETH_DST, "NXM_OF_ETH_DST", - OXM_OF_ETH_DST, "OXM_OF_ETH_DST", + OXM_OF_ETH_DST, "OXM_OF_ETH_DST", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, /* Bitwise masking only with NXM and OF11+! */ -1, @@ -287,7 +287,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, false, NXM_OF_ETH_TYPE, "NXM_OF_ETH_TYPE", - OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE", + OXM_OF_ETH_TYPE, "OXM_OF_ETH_TYPE", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NONE, -1, @@ -301,7 +301,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", - NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", + NXM_OF_VLAN_TCI, "NXM_OF_VLAN_TCI", 0, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -313,7 +313,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -325,7 +325,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID", - OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID", + OXM_OF_VLAN_VID, "OXM_OF_VLAN_VID", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -337,7 +337,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_NONE, true, 0, NULL, - 0, NULL, + 0, NULL, 0, OFPUTIL_P_ANY, /* Will be mapped to NXM and OXM. */ OFPUTIL_P_NONE, -1, @@ -349,7 +349,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_VLAN_VID, true, OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP", - OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP", + OXM_OF_VLAN_PCP, "OXM_OF_VLAN_PCP", OFP12_VERSION, OFPUTIL_P_ANY, /* Will be mapped to OF10 and NXM. */ OFPUTIL_P_NONE, -1, @@ -366,7 +366,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_MPLS, true, OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL", - OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL", + OXM_OF_MPLS_LABEL, "OXM_OF_MPLS_LABEL", OFP12_VERSION, OFPUTIL_P_NXM_OF11_UP, OFPUTIL_P_NONE, -1, @@ -378,7 +378,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_MPLS, true, OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC", - OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC", + OXM_OF_MPLS_TC, "OXM_OF_MPLS_TC", OFP12_VERSION, OFPUTIL_P_NXM_OF11_UP, OFPUTIL_P_NONE, -1, @@ -390,7 +390,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_MPLS, false, OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS", - OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS", + OXM_OF_MPLS_BOS, "OXM_OF_MPLS_BOS", OFP13_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NONE, -1, @@ -408,7 +408,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IPV4, true, NXM_OF_IP_SRC, "NXM_OF_IP_SRC", - OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC", + OXM_OF_IPV4_SRC, "OXM_OF_IPV4_SRC", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, FLOW_U32OFS(nw_src), @@ -420,7 +420,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IPV4, true, NXM_OF_IP_DST, "NXM_OF_IP_DST", - OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST", + OXM_OF_IPV4_DST, "OXM_OF_IPV4_DST", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, FLOW_U32OFS(nw_dst), @@ -434,7 +434,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IPV6, true, NXM_NX_IPV6_SRC, "NXM_NX_IPV6_SRC", - OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC", + OXM_OF_IPV6_SRC, "OXM_OF_IPV6_SRC", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, FLOW_U32OFS(ipv6_src), @@ -446,7 +446,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IPV6, true, NXM_NX_IPV6_DST, "NXM_NX_IPV6_DST", - OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST", + OXM_OF_IPV6_DST, "OXM_OF_IPV6_DST", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, FLOW_U32OFS(ipv6_dst), @@ -459,7 +459,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IPV6, false, NXM_NX_IPV6_LABEL, "NXM_NX_IPV6_LABEL", - OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL", + OXM_OF_IPV6_FLABEL, "OXM_OF_IPV6_FLABEL", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -473,7 +473,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, false, NXM_OF_IP_PROTO, "NXM_OF_IP_PROTO", - OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO", + OXM_OF_IP_PROTO, "OXM_OF_IP_PROTO", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NONE, -1, @@ -485,7 +485,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, true, NXM_OF_IP_TOS, "NXM_OF_IP_TOS", - NXM_OF_IP_TOS, "NXM_OF_IP_TOS", + NXM_OF_IP_TOS, "NXM_OF_IP_TOS", 0, OFPUTIL_P_ANY, /* Will be shifted for OXM. */ OFPUTIL_P_NONE, -1, @@ -497,7 +497,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, true, OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP", - OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP", + OXM_OF_IP_DSCP, "OXM_OF_IP_DSCP", OFP12_VERSION, OFPUTIL_P_ANY, /* Will be shifted for non-OXM. */ OFPUTIL_P_NONE, -1, @@ -509,7 +509,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, true, NXM_NX_IP_ECN, "NXM_NX_IP_ECN", - OXM_OF_IP_ECN, "OXM_OF_IP_ECN", + OXM_OF_IP_ECN, "OXM_OF_IP_ECN", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NONE, -1, @@ -521,7 +521,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, true, NXM_NX_IP_TTL, "NXM_NX_IP_TTL", - NXM_NX_IP_TTL, "NXM_NX_IP_TTL", + NXM_NX_IP_TTL, "NXM_NX_IP_TTL", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NONE, -1, @@ -533,7 +533,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_IP_ANY, false, NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG", - NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG", + NXM_NX_IP_FRAG, "NXM_NX_IP_FRAG", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -547,7 +547,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ARP, true, NXM_OF_ARP_OP, "NXM_OF_ARP_OP", - OXM_OF_ARP_OP, "OXM_OF_ARP_OP", + OXM_OF_ARP_OP, "OXM_OF_ARP_OP", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NONE, -1, @@ -559,7 +559,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ARP, true, NXM_OF_ARP_SPA, "NXM_OF_ARP_SPA", - OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA", + OXM_OF_ARP_SPA, "OXM_OF_ARP_SPA", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, -1, @@ -571,7 +571,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ARP, true, NXM_OF_ARP_TPA, "NXM_OF_ARP_TPA", - OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA", + OXM_OF_ARP_TPA, "OXM_OF_ARP_TPA", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OF11_UP, -1, @@ -583,7 +583,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ARP, true, NXM_NX_ARP_SHA, "NXM_NX_ARP_SHA", - OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA", + OXM_OF_ARP_SHA, "OXM_OF_ARP_SHA", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -595,7 +595,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ARP, true, NXM_NX_ARP_THA, "NXM_NX_ARP_THA", - OXM_OF_ARP_THA, "OXM_OF_ARP_THA", + OXM_OF_ARP_THA, "OXM_OF_ARP_THA", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -613,7 +613,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_TCP, true, NXM_OF_TCP_SRC, "NXM_OF_TCP_SRC", - OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC", + OXM_OF_TCP_SRC, "OXM_OF_TCP_SRC", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -625,7 +625,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_TCP, true, NXM_OF_TCP_DST, "NXM_OF_TCP_DST", - OXM_OF_TCP_DST, "OXM_OF_TCP_DST", + OXM_OF_TCP_DST, "OXM_OF_TCP_DST", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -637,7 +637,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_TCP, false, NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS", - NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS", + NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS", 0, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -651,7 +651,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_UDP, true, NXM_OF_UDP_SRC, "NXM_OF_UDP_SRC", - OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC", + OXM_OF_UDP_SRC, "OXM_OF_UDP_SRC", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -663,7 +663,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_UDP, true, NXM_OF_UDP_DST, "NXM_OF_UDP_DST", - OXM_OF_UDP_DST, "OXM_OF_UDP_DST", + OXM_OF_UDP_DST, "OXM_OF_UDP_DST", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -677,7 +677,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_SCTP, true, OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC", - OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC", + OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC", OFP12_VERSION, OFPUTIL_P_NXM_OF11_UP, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -689,7 +689,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_SCTP, true, OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST", - OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST", + OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST", OFP12_VERSION, OFPUTIL_P_NXM_OF11_UP, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -703,7 +703,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ICMPV4, false, NXM_OF_ICMP_TYPE, "NXM_OF_ICMP_TYPE", - OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE", + OXM_OF_ICMPV4_TYPE, "OXM_OF_ICMPV4_TYPE", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NONE, -1, @@ -715,7 +715,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ICMPV4, false, NXM_OF_ICMP_CODE, "NXM_OF_ICMP_CODE", - OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE", + OXM_OF_ICMPV4_CODE, "OXM_OF_ICMPV4_CODE", OFP12_VERSION, OFPUTIL_P_ANY, OFPUTIL_P_NONE, -1, @@ -729,7 +729,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ICMPV6, false, NXM_NX_ICMPV6_TYPE, "NXM_NX_ICMPV6_TYPE", - OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE", + OXM_OF_ICMPV6_TYPE, "OXM_OF_ICMPV6_TYPE", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NONE, -1, @@ -741,7 +741,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ICMPV6, false, NXM_NX_ICMPV6_CODE, "NXM_NX_ICMPV6_CODE", - OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE", + OXM_OF_ICMPV6_CODE, "OXM_OF_ICMPV6_CODE", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NONE, -1, @@ -759,7 +759,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ND, false, NXM_NX_ND_TARGET, "NXM_NX_ND_TARGET", - OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET", + OXM_OF_IPV6_ND_TARGET, "OXM_OF_IPV6_ND_TARGET", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -771,7 +771,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ND_SOLICIT, false, NXM_NX_ND_SLL, "NXM_NX_ND_SLL", - OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL", + OXM_OF_IPV6_ND_SLL, "OXM_OF_IPV6_ND_SLL", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -783,7 +783,7 @@ const struct mf_field mf_fields[MFF_N_IDS] = { MFP_ND_ADVERT, false, NXM_NX_ND_TLL, "NXM_NX_ND_TLL", - OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL", + OXM_OF_IPV6_ND_TLL, "OXM_OF_IPV6_ND_TLL", OFP12_VERSION, OFPUTIL_P_NXM_OXM_ANY, OFPUTIL_P_NXM_OXM_ANY, -1, @@ -894,6 +894,16 @@ mf_from_nxm_header__(uint32_t header) return NULL; } +uint32_t +mf_oxm_header(enum mf_field_id id, enum ofp_version oxm_version) +{ + const struct mf_field *field = mf_from_id(id); + + return (oxm_version >= field->oxm_version + ? field->oxm_header + : field->nxm_header); +} + /* Returns true if 'wc' wildcards all the bits in field 'mf', false if 'wc' * specifies at least one bit in the field. * diff --git a/lib/meta-flow.h b/lib/meta-flow.h index d02d320..7a4b8dc 100644 --- a/lib/meta-flow.h +++ b/lib/meta-flow.h @@ -276,6 +276,11 @@ struct mf_field { * * - NXM and OXM both define such a field: nxm_header and oxm_header will * both be nonzero and different, similarly for nxm_name and oxm_name. + * In this case, 'oxm_version' is significant: if it is greater than + * OFP12_VERSION, then only that version of OpenFlow introduced this + * OXM header, so ovs-vswitchd should send 'nxm_header' instead with + * earlier protocol versions to avoid confusing controllers that were + * using a previous Open vSwitch extension. * * - Only NXM or only OXM defines such a field: nxm_header and oxm_header * will both have the same value (either an OXM_* or NXM_* value) and @@ -285,11 +290,14 @@ struct mf_field { * NXM formatted match, since it will be an NXM_* constant when possible * for compatibility with OpenFlow implementations that expect that, with * OXM_* constants used for fields that OXM adds. Conversely, 'oxm_header' - * is the header to use when outputting an OXM formatted match. */ + * is the header to use when outputting an OXM formatted match to an + * OpenFlow connection of version 'oxm_version' or above (and otherwise + * 'nxm_header'). */ uint32_t nxm_header; /* An NXM_* (or OXM_*) constant. */ const char *nxm_name; /* The nxm_header constant's name. */ uint32_t oxm_header; /* An OXM_* (or NXM_*) constant. */ const char *oxm_name; /* The oxm_header constant's name */ + enum ofp_version oxm_version; /* OpenFlow version that added oxm_header. */ /* Usable protocols. * NXM and OXM are extensible, allowing later extensions to be sent in @@ -352,6 +360,9 @@ mf_from_id(enum mf_field_id id) return &mf_fields[id]; } +/* NXM and OXM protocol headers. */ +uint32_t mf_oxm_header(enum mf_field_id, enum ofp_version oxm_version); + /* Inspecting wildcarded bits. */ bool mf_is_all_wild(const struct mf_field *, const struct flow_wildcards *); diff --git a/lib/nx-match.c b/lib/nx-match.c index 957c82b..295eec0 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -499,19 +499,19 @@ nxm_put_frag(struct ofpbuf *b, const struct match *match) /* Appends to 'b' a set of OXM or NXM matches for the IPv4 or IPv6 fields in * 'match'. */ static void -nxm_put_ip(struct ofpbuf *b, const struct match *match, bool oxm) +nxm_put_ip(struct ofpbuf *b, const struct match *match, enum ofp_version oxm) { const struct flow *flow = &match->flow; if (flow->dl_type == htons(ETH_TYPE_IP)) { - nxm_put_32m(b, oxm ? OXM_OF_IPV4_SRC : NXM_OF_IP_SRC, + nxm_put_32m(b, mf_oxm_header(MFF_IPV4_SRC, oxm), flow->nw_src, match->wc.masks.nw_src); - nxm_put_32m(b, oxm ? OXM_OF_IPV4_DST : NXM_OF_IP_DST, + nxm_put_32m(b, mf_oxm_header(MFF_IPV4_DST, oxm), flow->nw_dst, match->wc.masks.nw_dst); } else { - nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_SRC : NXM_NX_IPV6_SRC, + nxm_put_ipv6(b, mf_oxm_header(MFF_IPV6_SRC, oxm), &flow->ipv6_src, &match->wc.masks.ipv6_src); - nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_DST : NXM_NX_IPV6_DST, + nxm_put_ipv6(b, mf_oxm_header(MFF_IPV6_DST, oxm), &flow->ipv6_dst, &match->wc.masks.ipv6_dst); } @@ -519,74 +519,74 @@ nxm_put_ip(struct ofpbuf *b, const struct match *match, bool oxm) if (match->wc.masks.nw_tos & IP_DSCP_MASK) { if (oxm) { - nxm_put_8(b, OXM_OF_IP_DSCP, flow->nw_tos >> 2); + nxm_put_8(b, mf_oxm_header(MFF_IP_DSCP_SHIFTED, oxm), + flow->nw_tos >> 2); } else { - nxm_put_8(b, NXM_OF_IP_TOS, flow->nw_tos & IP_DSCP_MASK); + nxm_put_8(b, mf_oxm_header(MFF_IP_DSCP, oxm), + flow->nw_tos & IP_DSCP_MASK); } } if (match->wc.masks.nw_tos & IP_ECN_MASK) { - nxm_put_8(b, oxm ? OXM_OF_IP_ECN : NXM_NX_IP_ECN, + nxm_put_8(b, mf_oxm_header(MFF_IP_ECN, oxm), flow->nw_tos & IP_ECN_MASK); } if (!oxm && match->wc.masks.nw_ttl) { - nxm_put_8(b, NXM_NX_IP_TTL, flow->nw_ttl); + nxm_put_8(b, mf_oxm_header(MFF_IP_TTL, oxm), flow->nw_ttl); } - nxm_put_32m(b, oxm ? OXM_OF_IPV6_FLABEL : NXM_NX_IPV6_LABEL, + nxm_put_32m(b, mf_oxm_header(MFF_IPV6_LABEL, oxm), flow->ipv6_label, match->wc.masks.ipv6_label); if (match->wc.masks.nw_proto) { - nxm_put_8(b, oxm ? OXM_OF_IP_PROTO : NXM_OF_IP_PROTO, flow->nw_proto); + nxm_put_8(b, mf_oxm_header(MFF_IP_PROTO, oxm), flow->nw_proto); if (flow->nw_proto == IPPROTO_TCP) { - nxm_put_16m(b, oxm ? OXM_OF_TCP_SRC : NXM_OF_TCP_SRC, + nxm_put_16m(b, mf_oxm_header(MFF_TCP_SRC, oxm), flow->tp_src, match->wc.masks.tp_src); - nxm_put_16m(b, oxm ? OXM_OF_TCP_DST : NXM_OF_TCP_DST, + nxm_put_16m(b, mf_oxm_header(MFF_TCP_DST, oxm), flow->tp_dst, match->wc.masks.tp_dst); - nxm_put_16m(b, NXM_NX_TCP_FLAGS, + nxm_put_16m(b, mf_oxm_header(MFF_TCP_FLAGS, oxm), flow->tcp_flags, match->wc.masks.tcp_flags); } else if (flow->nw_proto == IPPROTO_UDP) { - nxm_put_16m(b, oxm ? OXM_OF_UDP_SRC : NXM_OF_UDP_SRC, + nxm_put_16m(b, mf_oxm_header(MFF_UDP_SRC, oxm), flow->tp_src, match->wc.masks.tp_src); - nxm_put_16m(b, oxm ? OXM_OF_UDP_DST : NXM_OF_UDP_DST, + nxm_put_16m(b, mf_oxm_header(MFF_UDP_DST, oxm), flow->tp_dst, match->wc.masks.tp_dst); } else if (flow->nw_proto == IPPROTO_SCTP) { - nxm_put_16m(b, OXM_OF_SCTP_SRC, flow->tp_src, + nxm_put_16m(b, mf_oxm_header(MFF_SCTP_SRC, oxm), flow->tp_src, match->wc.masks.tp_src); - nxm_put_16m(b, OXM_OF_SCTP_DST, flow->tp_dst, + nxm_put_16m(b, mf_oxm_header(MFF_SCTP_DST, oxm), flow->tp_dst, match->wc.masks.tp_dst); } else if (is_icmpv4(flow)) { if (match->wc.masks.tp_src) { - nxm_put_8(b, oxm ? OXM_OF_ICMPV4_TYPE : NXM_OF_ICMP_TYPE, + nxm_put_8(b, mf_oxm_header(MFF_ICMPV4_TYPE, oxm), ntohs(flow->tp_src)); } if (match->wc.masks.tp_dst) { - nxm_put_8(b, oxm ? OXM_OF_ICMPV4_CODE : NXM_OF_ICMP_CODE, + nxm_put_8(b, mf_oxm_header(MFF_ICMPV4_CODE, oxm), ntohs(flow->tp_dst)); } } else if (is_icmpv6(flow)) { if (match->wc.masks.tp_src) { - nxm_put_8(b, oxm ? OXM_OF_ICMPV6_TYPE : NXM_NX_ICMPV6_TYPE, + nxm_put_8(b, mf_oxm_header(MFF_ICMPV6_TYPE, oxm), ntohs(flow->tp_src)); } if (match->wc.masks.tp_dst) { - nxm_put_8(b, oxm ? OXM_OF_ICMPV6_CODE : NXM_NX_ICMPV6_CODE, + nxm_put_8(b, mf_oxm_header(MFF_ICMPV6_CODE, oxm), ntohs(flow->tp_dst)); } if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT) || flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { - nxm_put_ipv6(b, oxm ? OXM_OF_IPV6_ND_TARGET : NXM_NX_ND_TARGET, + nxm_put_ipv6(b, mf_oxm_header(MFF_ND_TARGET, oxm), &flow->nd_target, &match->wc.masks.nd_target); if (flow->tp_src == htons(ND_NEIGHBOR_SOLICIT)) { - uint32_t field = oxm ? OXM_OF_IPV6_ND_SLL : NXM_NX_ND_SLL; - nxm_put_eth_masked(b, field, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ND_SLL, oxm), flow->arp_sha, match->wc.masks.arp_sha); } if (flow->tp_src == htons(ND_NEIGHBOR_ADVERT)) { - uint32_t field = oxm ? OXM_OF_IPV6_ND_TLL : NXM_NX_ND_TLL; - nxm_put_eth_masked(b, field, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ND_TLL, oxm), flow->arp_tha, match->wc.masks.arp_tha); } } @@ -598,6 +598,9 @@ nxm_put_ip(struct ofpbuf *b, const struct match *match, bool oxm) * Flow Stats Requests messages, a 'cookie' and 'cookie_mask' may be supplied. * Otherwise, 'cookie_mask' should be zero. * + * Specify 'oxm' as 0 to express the match in NXM format; otherwise, specify + * 'oxm' as the OpenFlow version number for the OXM format to use. + * * This function can cause 'b''s data to be reallocated. * * Returns the number of bytes appended to 'b', excluding padding. @@ -605,7 +608,7 @@ nxm_put_ip(struct ofpbuf *b, const struct match *match, bool oxm) * If 'match' is a catch-all rule that matches every packet, then this function * appends nothing to 'b' and returns 0. */ static int -nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, +nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match, ovs_be64 cookie, ovs_be64 cookie_mask) { const struct flow *flow = &match->flow; @@ -632,18 +635,20 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, if (match->wc.masks.in_port.ofp_port) { ofp_port_t in_port = flow->in_port.ofp_port; if (oxm) { - nxm_put_32(b, OXM_OF_IN_PORT, ofputil_port_to_ofp11(in_port)); + nxm_put_32(b, mf_oxm_header(MFF_IN_PORT_OXM, oxm), + ofputil_port_to_ofp11(in_port)); } else { - nxm_put_16(b, NXM_OF_IN_PORT, htons(ofp_to_u16(in_port))); + nxm_put_16(b, mf_oxm_header(MFF_IN_PORT, oxm), + htons(ofp_to_u16(in_port))); } } /* Ethernet. */ - nxm_put_eth_masked(b, oxm ? OXM_OF_ETH_SRC : NXM_OF_ETH_SRC, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ETH_SRC, oxm), flow->dl_src, match->wc.masks.dl_src); - nxm_put_eth_masked(b, oxm ? OXM_OF_ETH_DST : NXM_OF_ETH_DST, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ETH_DST, oxm), flow->dl_dst, match->wc.masks.dl_dst); - nxm_put_16m(b, oxm ? OXM_OF_ETH_TYPE : NXM_OF_ETH_TYPE, + nxm_put_16m(b, mf_oxm_header(MFF_ETH_TYPE, oxm), ofputil_dl_type_to_openflow(flow->dl_type), match->wc.masks.dl_type); @@ -654,32 +659,35 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, ovs_be16 mask = match->wc.masks.vlan_tci & VID_CFI_MASK; if (mask == htons(VLAN_VID_MASK | VLAN_CFI)) { - nxm_put_16(b, OXM_OF_VLAN_VID, vid); + nxm_put_16(b, mf_oxm_header(MFF_VLAN_VID, oxm), vid); } else if (mask) { - nxm_put_16m(b, OXM_OF_VLAN_VID, vid, mask); + nxm_put_16m(b, mf_oxm_header(MFF_VLAN_VID, oxm), vid, mask); } if (vid && vlan_tci_to_pcp(match->wc.masks.vlan_tci)) { - nxm_put_8(b, OXM_OF_VLAN_PCP, vlan_tci_to_pcp(flow->vlan_tci)); + nxm_put_8(b, mf_oxm_header(MFF_VLAN_PCP, oxm), + vlan_tci_to_pcp(flow->vlan_tci)); } } else { - nxm_put_16m(b, NXM_OF_VLAN_TCI, flow->vlan_tci, + nxm_put_16m(b, mf_oxm_header(MFF_VLAN_TCI, oxm), flow->vlan_tci, match->wc.masks.vlan_tci); } /* MPLS. */ if (eth_type_mpls(flow->dl_type)) { if (match->wc.masks.mpls_lse[0] & htonl(MPLS_TC_MASK)) { - nxm_put_8(b, OXM_OF_MPLS_TC, mpls_lse_to_tc(flow->mpls_lse[0])); + nxm_put_8(b, mf_oxm_header(MFF_MPLS_TC, oxm), + mpls_lse_to_tc(flow->mpls_lse[0])); } if (match->wc.masks.mpls_lse[0] & htonl(MPLS_BOS_MASK)) { - nxm_put_8(b, OXM_OF_MPLS_BOS, mpls_lse_to_bos(flow->mpls_lse[0])); + nxm_put_8(b, mf_oxm_header(MFF_MPLS_BOS, oxm), + mpls_lse_to_bos(flow->mpls_lse[0])); } if (match->wc.masks.mpls_lse[0] & htonl(MPLS_LABEL_MASK)) { - nxm_put_32(b, OXM_OF_MPLS_LABEL, + nxm_put_32(b, mf_oxm_header(MFF_MPLS_LABEL, oxm), htonl(mpls_lse_to_label(flow->mpls_lse[0]))); } } @@ -691,41 +699,42 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, flow->dl_type == htons(ETH_TYPE_RARP)) { /* ARP. */ if (match->wc.masks.nw_proto) { - nxm_put_16(b, oxm ? OXM_OF_ARP_OP : NXM_OF_ARP_OP, + nxm_put_16(b, mf_oxm_header(MFF_ARP_OP, oxm), htons(flow->nw_proto)); } - nxm_put_32m(b, oxm ? OXM_OF_ARP_SPA : NXM_OF_ARP_SPA, + nxm_put_32m(b, mf_oxm_header(MFF_ARP_SPA, oxm), flow->nw_src, match->wc.masks.nw_src); - nxm_put_32m(b, oxm ? OXM_OF_ARP_TPA : NXM_OF_ARP_TPA, + nxm_put_32m(b, mf_oxm_header(MFF_ARP_TPA, oxm), flow->nw_dst, match->wc.masks.nw_dst); - nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_SHA : NXM_NX_ARP_SHA, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ARP_SHA, oxm), flow->arp_sha, match->wc.masks.arp_sha); - nxm_put_eth_masked(b, oxm ? OXM_OF_ARP_THA : NXM_NX_ARP_THA, + nxm_put_eth_masked(b, mf_oxm_header(MFF_ARP_THA, oxm), flow->arp_tha, match->wc.masks.arp_tha); } /* Tunnel ID. */ - nxm_put_64m(b, oxm ? OXM_OF_TUNNEL_ID : NXM_NX_TUN_ID, + nxm_put_64m(b, mf_oxm_header(MFF_TUN_ID, oxm), flow->tunnel.tun_id, match->wc.masks.tunnel.tun_id); /* Other tunnel metadata. */ - nxm_put_32m(b, NXM_NX_TUN_IPV4_SRC, + nxm_put_32m(b, mf_oxm_header(MFF_TUN_SRC, oxm), flow->tunnel.ip_src, match->wc.masks.tunnel.ip_src); - nxm_put_32m(b, NXM_NX_TUN_IPV4_DST, + nxm_put_32m(b, mf_oxm_header(MFF_TUN_DST, oxm), flow->tunnel.ip_dst, match->wc.masks.tunnel.ip_dst); /* Registers. */ for (i = 0; i < FLOW_N_REGS; i++) { - nxm_put_32m(b, NXM_NX_REG(i), + nxm_put_32m(b, mf_oxm_header(MFF_REG0 + i, oxm), htonl(flow->regs[i]), htonl(match->wc.masks.regs[i])); } /* Mark. */ - nxm_put_32m(b, NXM_NX_PKT_MARK, htonl(flow->pkt_mark), + nxm_put_32m(b, mf_oxm_header(MFF_PKT_MARK, oxm), htonl(flow->pkt_mark), htonl(match->wc.masks.pkt_mark)); /* OpenFlow 1.1+ Metadata. */ - nxm_put_64m(b, OXM_OF_METADATA, flow->metadata, match->wc.masks.metadata); + nxm_put_64m(b, mf_oxm_header(MFF_METADATA, oxm), + flow->metadata, match->wc.masks.metadata); /* Cookie. */ nxm_put_64m(b, NXM_NX_COOKIE, cookie, cookie_mask); @@ -748,23 +757,26 @@ int nx_put_match(struct ofpbuf *b, const struct match *match, ovs_be64 cookie, ovs_be64 cookie_mask) { - int match_len = nx_put_raw(b, false, match, cookie, cookie_mask); + int match_len = nx_put_raw(b, 0, match, cookie, cookie_mask); ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8)); return match_len; } - -/* Appends to 'b' an struct ofp11_match_header followed by the oxm format that +/* Appends to 'b' an struct ofp11_match_header followed by the OXM format that * expresses 'cr', plus enough zero bytes to pad the data appended out to a * multiple of 8. * + * OXM differs slightly among versions of OpenFlow. Specify the OpenFlow + * version in use as 'version'. + * * This function can cause 'b''s data to be reallocated. * * Returns the number of bytes appended to 'b', excluding the padding. Never * returns zero. */ int -oxm_put_match(struct ofpbuf *b, const struct match *match) +oxm_put_match(struct ofpbuf *b, const struct match *match, + enum ofp_version version) { int match_len; struct ofp11_match_header *omh; @@ -772,7 +784,8 @@ oxm_put_match(struct ofpbuf *b, const struct match *match) ovs_be64 cookie = htonll(0), cookie_mask = htonll(0); ofpbuf_put_uninit(b, sizeof *omh); - match_len = nx_put_raw(b, true, match, cookie, cookie_mask) + sizeof *omh; + match_len = (nx_put_raw(b, version, match, cookie, cookie_mask) + + sizeof *omh); ofpbuf_put_zeros(b, PAD_SIZE(match_len, 8)); omh = ofpbuf_at(b, start_len, sizeof *omh); diff --git a/lib/nx-match.h b/lib/nx-match.h index edd7948..077f299 100644 --- a/lib/nx-match.h +++ b/lib/nx-match.h @@ -52,7 +52,7 @@ enum ofperr oxm_pull_match(struct ofpbuf *, struct match *); enum ofperr oxm_pull_match_loose(struct ofpbuf *, struct match *); int nx_put_match(struct ofpbuf *, const struct match *, ovs_be64 cookie, ovs_be64 cookie_mask); -int oxm_put_match(struct ofpbuf *, const struct match *); +int oxm_put_match(struct ofpbuf *, const struct match *, enum ofp_version); char *nx_match_to_string(const uint8_t *, unsigned int match_len); char *oxm_match_to_string(const struct ofpbuf *, unsigned int match_len); diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index ce14004..cc1f9a0 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -825,14 +825,15 @@ set_field_from_openflow(const struct ofp12_action_set_field *oasf, static void set_field_to_openflow12(const struct ofpact_set_field *sf, - struct ofpbuf *openflow) + struct ofpbuf *openflow, + enum ofp_version version) { uint16_t padded_value_len = ROUND_UP(sf->field->n_bytes, 8); struct ofp12_action_set_field *oasf; char *value; oasf = ofputil_put_OFPAT12_SET_FIELD(openflow); - oasf->dst = htonl(sf->field->oxm_header); + oasf->dst = htonl(mf_oxm_header(sf->field->id, version)); oasf->len = htons(sizeof *oasf + padded_value_len); value = ofpbuf_put_zeros(openflow, padded_value_len); @@ -1080,7 +1081,7 @@ set_field_to_openflow(const struct ofpact_set_field *sf, struct ofp_header *oh = (struct ofp_header *)openflow->frame; if (oh->version >= OFP12_VERSION) { - set_field_to_openflow12(sf, openflow); + set_field_to_openflow12(sf, openflow, oh->version); } else if (oh->version == OFP11_VERSION) { set_field_to_openflow11(sf, openflow); } else if (oh->version == OFP10_VERSION) { diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 4bf101a..e29c454 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -665,7 +665,8 @@ ofputil_put_ofp11_match(struct ofpbuf *b, const struct match *match, case OFPUTIL_P_OF13_OXM: case OFPUTIL_P_OF14_OXM: case OFPUTIL_P_OF15_OXM: - return oxm_put_match(b, match); + return oxm_put_match(b, match, + ofputil_protocol_to_ofp_version(protocol)); } OVS_NOT_REACHED(); @@ -1068,7 +1069,7 @@ ofputil_protocols_from_string(const char *s) return protocols; } -static int +enum ofp_version ofputil_version_from_string(const char *s) { if (!strcasecmp(s, "OpenFlow10")) { @@ -2929,7 +2930,7 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs, struct ofp11_flow_stats *ofs; ofpbuf_put_uninit(reply, sizeof *ofs); - oxm_put_match(reply, &fs->match); + oxm_put_match(reply, &fs->match, version); ofpacts_put_openflow_instructions(fs->ofpacts, fs->ofpacts_len, reply, version); @@ -3473,7 +3474,7 @@ ofputil_encode_ofp12_packet_in(const struct ofputil_packet_in *pin, htonl(0), (sizeof(struct flow_metadata) * 2 + 2 + pin->packet_len)); ofpbuf_put_zeros(packet, packet_in_size); - oxm_put_match(packet, &match); + oxm_put_match(packet, &match, ofputil_protocol_to_ofp_version(protocol)); ofpbuf_put_zeros(packet, 2); ofpbuf_put(packet, pin->packet, pin->packet_len); diff --git a/lib/ofp-util.h b/lib/ofp-util.h index f0b6604..ce6045b 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -170,6 +170,8 @@ void ofputil_format_version_name(struct ds *, enum ofp_version); void ofputil_format_version_bitmap(struct ds *msg, uint32_t bitmap); void ofputil_format_version_bitmap_names(struct ds *msg, uint32_t bitmap); +enum ofp_version ofputil_version_from_string(const char *s); + uint32_t ofputil_protocols_to_version_bitmap(enum ofputil_protocol); enum ofputil_protocol ofputil_protocols_from_version_bitmap(uint32_t bitmap); diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index bda8666..88e4220 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -1890,7 +1890,7 @@ OXM_OF_ETH_TYPE(0800) OXM_OF_IP_PROTO(3a) OXM_OF_ICMPV6_TYPE(88) OXM_OF_IPV6_ND_ # Invalid field number. 01020304(1111/2222) ]) -AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' --strict parse-oxm < oxm.txt], +AT_CHECK([ovs-ofctl '-vPATTERN:console:%c|%p|%m' --strict parse-oxm OpenFlow12 < oxm.txt], [0], [dnl <any> @@ -2123,11 +2123,11 @@ AT_DATA([oxm.txt], [dnl OXM_OF_IN_PORT(00000001), 01020304(1111/2222), OXM_OF_ETH_TYPE(0800) ]) -AT_CHECK([ovs-ofctl --strict parse-oxm < oxm.txt], [0], [dnl +AT_CHECK([ovs-ofctl --strict parse-oxm OpenFlow12 < oxm.txt], [0], [dnl nx_pull_match() returned error OFPBMC_BAD_FIELD ]) -AT_CHECK([ovs-ofctl parse-oxm < oxm.txt], [0], [dnl +AT_CHECK([ovs-ofctl parse-oxm OpenFlow12 < oxm.txt], [0], [dnl OXM_OF_IN_PORT(00000001), OXM_OF_ETH_TYPE(0800) ]) AT_CLEANUP diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c index 986c18f..d62d328 100644 --- a/utilities/ovs-ofctl.c +++ b/utilities/ovs-ofctl.c @@ -2823,7 +2823,7 @@ ofctl_parse_flows(int argc OVS_UNUSED, char *argv[]) } static void -ofctl_parse_nxm__(bool oxm) +ofctl_parse_nxm__(bool oxm, enum ofp_version version) { struct ds in; @@ -2868,7 +2868,7 @@ ofctl_parse_nxm__(bool oxm) ofpbuf_uninit(&nx_match); ofpbuf_init(&nx_match, 0); if (oxm) { - match_len = oxm_put_match(&nx_match, &match); + match_len = oxm_put_match(&nx_match, &match, version); out = oxm_match_to_string(&nx_match, match_len); } else { match_len = nx_put_match(&nx_match, &match, @@ -2894,16 +2894,22 @@ ofctl_parse_nxm__(bool oxm) static void ofctl_parse_nxm(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) { - return ofctl_parse_nxm__(false); + return ofctl_parse_nxm__(false, 0); } -/* "parse-oxm": reads a series of OXM nx_match specifications as strings from - * stdin, does some internal fussing with them, and then prints them back as - * strings on stdout. */ +/* "parse-oxm VERSION": reads a series of OXM nx_match specifications as + * strings from stdin, does some internal fussing with them, and then prints + * them back as strings on stdout. VERSION must specify an OpenFlow version, + * e.g. "OpenFlow12". */ static void -ofctl_parse_oxm(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) +ofctl_parse_oxm(int argc OVS_UNUSED, char *argv[]) { - return ofctl_parse_nxm__(true); + enum ofp_version version = ofputil_version_from_string(argv[1]); + if (version < OFP12_VERSION) { + ovs_fatal(0, "%s: not a valid version for OXM", argv[1]); + } + + return ofctl_parse_nxm__(true, version); } static void @@ -3349,7 +3355,7 @@ ofctl_check_vlan(int argc OVS_UNUSED, char *argv[]) /* Convert to and from OXM. */ ofpbuf_init(&nxm, 0); - nxm_match_len = oxm_put_match(&nxm, &match); + nxm_match_len = oxm_put_match(&nxm, &match, OFP12_VERSION); nxm_s = oxm_match_to_string(&nxm, nxm_match_len); error = oxm_pull_match(&nxm, &nxm_match); printf("OXM: %s -> ", nxm_s); @@ -3539,7 +3545,7 @@ static const struct command all_commands[] = { { "parse-flows", 1, 1, ofctl_parse_flows }, { "parse-nx-match", 0, 0, ofctl_parse_nxm }, { "parse-nxm", 0, 0, ofctl_parse_nxm }, - { "parse-oxm", 0, 0, ofctl_parse_oxm }, + { "parse-oxm", 1, 1, ofctl_parse_oxm }, { "parse-ofp10-actions", 0, 0, ofctl_parse_ofp10_actions }, { "parse-ofp10-match", 0, 0, ofctl_parse_ofp10_match }, { "parse-ofp11-match", 0, 0, ofctl_parse_ofp11_match }, -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev