Output set field actions as standard OF1.0/1.1 set actions whenever possible.
Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- lib/ofp-util.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/ovs-ofctl.at | 4 +- 2 files changed, 162 insertions(+), 2 deletions(-) diff --git a/lib/ofp-util.c b/lib/ofp-util.c index c9d42a9..17642d2 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -6164,9 +6164,169 @@ ofputil_set_field_to_openflow(const struct ofpact_set_field *sf, set_field_to_ofast(sf, openflow); return; } + /* Check if can convert to standard actions. */ mf = ofpact_set_field_get_field(sf); + if (oh->version == OFP10_VERSION) { + switch ((int)mf->id) { + + case MFF_VLAN_TCI: + ofputil_put_OFPAT10_SET_VLAN_VID(openflow)->vlan_vid + = sf->be16 & htons(VLAN_VID_MASK); + ofputil_put_OFPAT10_SET_VLAN_PCP(openflow)->vlan_pcp + = vlan_tci_to_pcp(sf->be16); + return; + + case MFF_DL_VLAN: + case MFF_VLAN_VID: + ofputil_put_OFPAT10_SET_VLAN_VID(openflow)->vlan_vid + = sf->be16 & htons(VLAN_VID_MASK); + return; + + case MFF_DL_VLAN_PCP: + case MFF_VLAN_PCP: + ofputil_put_OFPAT10_SET_VLAN_PCP(openflow)->vlan_pcp + = sf->u8; + return; + + case MFF_ETH_SRC: + memcpy(ofputil_put_OFPAT10_SET_DL_SRC(openflow)->dl_addr, + sf->mac, ETH_ADDR_LEN); + return; + + case MFF_ETH_DST: + memcpy(ofputil_put_OFPAT10_SET_DL_DST(openflow)->dl_addr, + sf->mac, ETH_ADDR_LEN); + return; + + case MFF_IPV4_SRC: + ofputil_put_OFPAT10_SET_NW_SRC(openflow)->nw_addr + = sf->be32; + return; + + case MFF_IPV4_DST: + ofputil_put_OFPAT10_SET_NW_DST(openflow)->nw_addr + = sf->be32; + return; + + case MFF_IP_DSCP: + ofputil_put_OFPAT10_SET_NW_TOS(openflow)->nw_tos + = sf->u8; + return; + + case MFF_IP_DSCP_SHIFTED: + ofputil_put_OFPAT10_SET_NW_TOS(openflow)->nw_tos + = sf->u8 << 2; + return; + + case MFF_TCP_SRC: + case MFF_UDP_SRC: + ofputil_put_OFPAT10_SET_TP_SRC(openflow)->tp_port + = sf->be16; + return; + + case MFF_TCP_DST: + case MFF_UDP_DST: + ofputil_put_OFPAT10_SET_TP_DST(openflow)->tp_port + = sf->be16; + return; + } + } else { /* OpenFlow 1.1 */ + /* Check if can convert to standard actions. */ + switch ((int)mf->id) { + + case MFF_METADATA: + /* XXX: via WRITE METADATA instruction. May be hard to implement + * as instructions may be present only once each and in a specific + * order. */ + break; + + case MFF_VLAN_TCI: + ofputil_put_OFPAT11_SET_VLAN_VID(openflow)->vlan_vid + = sf->be16 & htons(VLAN_VID_MASK); + ofputil_put_OFPAT11_SET_VLAN_PCP(openflow)->vlan_pcp + = vlan_tci_to_pcp(sf->be16); + return; + + case MFF_DL_VLAN: + case MFF_VLAN_VID: + ofputil_put_OFPAT11_SET_VLAN_VID(openflow)->vlan_vid + = sf->be16 & htons(VLAN_VID_MASK); + return; + + case MFF_DL_VLAN_PCP: + case MFF_VLAN_PCP: + ofputil_put_OFPAT11_SET_VLAN_PCP(openflow)->vlan_pcp + = sf->u8; + return; + + case MFF_ETH_SRC: + memcpy(ofputil_put_OFPAT11_SET_DL_SRC(openflow)->dl_addr, + sf->mac, ETH_ADDR_LEN); + return; + + case MFF_ETH_DST: + memcpy(ofputil_put_OFPAT11_SET_DL_DST(openflow)->dl_addr, + sf->mac, ETH_ADDR_LEN); + return; + + case MFF_MPLS_LABEL: + /* ofputil_put_OFPAT11_SET_MPLS_LABEL(openflow)->label = + sf->be32; */ + break; + + case MFF_MPLS_TC: + /* ofputil_put_OFPAT11_SET_MPLS_TC(openflow)->tc = + sf->u8; */ + break; + + case MFF_IPV4_SRC: + ofputil_put_OFPAT11_SET_NW_SRC(openflow)->nw_addr + = sf->be32; + return; + + case MFF_IPV4_DST: + ofputil_put_OFPAT11_SET_NW_DST(openflow)->nw_addr + = sf->be32; + return; + + case MFF_IP_DSCP: + ofputil_put_OFPAT11_SET_NW_TOS(openflow)->nw_tos + = sf->u8; + return; + + case MFF_IP_DSCP_SHIFTED: + ofputil_put_OFPAT11_SET_NW_TOS(openflow)->nw_tos + = sf->u8 << 2; + return; + + case MFF_IP_ECN: + ofputil_put_OFPAT11_SET_NW_ECN(openflow)->nw_ecn + = sf->u8; + return; + + case MFF_IP_TTL: + ofputil_put_OFPAT11_SET_NW_TTL(openflow)->nw_ttl + = sf->u8; + return; + + case MFF_TCP_SRC: + case MFF_UDP_SRC: + case MFF_SCTP_SRC: + ofputil_put_OFPAT11_SET_TP_SRC(openflow)->tp_port + = sf->be16; + return; + + case MFF_TCP_DST: + case MFF_UDP_DST: + case MFF_SCTP_DST: + ofputil_put_OFPAT11_SET_TP_DST(openflow)->tp_port + = sf->be16; + return; + } + } + /* Convert to one or two REG_LOADs */ if (mf->n_bits > 64) { diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index f4ca4d5..9ceb4a9 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -131,7 +131,7 @@ OFPT_FLOW_MOD: ADD tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output: OFPT_FLOW_MOD: ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1 OFPT_FLOW_MOD: ADD priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535 OFPT_FLOW_MOD: ADD actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00 -OFPT_FLOW_MOD: ADD ip actions=load:0xa04034d->NXM_OF_IP_SRC[] +OFPT_FLOW_MOD: ADD ip actions=mod_nw_src:10.4.3.77 OFPT_FLOW_MOD: ADD sctp actions=drop OFPT_FLOW_MOD: ADD sctp actions=drop OFPT_FLOW_MOD: ADD in_port=0 actions=resubmit:0 @@ -168,7 +168,7 @@ OFPT_FLOW_MOD (OF1.1): ADD table:255 tcp,nw_src=192.168.0.3,tp_dst=80 actions=se OFPT_FLOW_MOD (OF1.1): ADD table:255 udp,nw_src=192.168.0.3,tp_dst=53 actions=mod_nw_ecn:2,output:1 OFPT_FLOW_MOD (OF1.1): ADD table:255 priority=60000 cookie:0x123456789abcdef hard:10 actions=CONTROLLER:65535 OFPT_FLOW_MOD (OF1.1): ADD table:255 actions=note:41.42.43.00.00.00,note:00.01.02.03.04.05.06.07.00.00.00.00.00.00,note:00.00.00.00.00.00 -OFPT_FLOW_MOD (OF1.1): ADD table:255 ip actions=mod_nw_ttl:1,load:0xa04034d->NXM_OF_IP_SRC[] +OFPT_FLOW_MOD (OF1.1): ADD table:255 ip actions=mod_nw_ttl:1,mod_nw_src:10.4.3.77 OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop OFPT_FLOW_MOD (OF1.1): ADD table:255 sctp actions=drop OFPT_FLOW_MOD (OF1.1): ADD table:255 in_port=0 actions=resubmit:0 -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev