From: Isaku Yamahata Date: Fri, 26 Oct 2012 04:43:19 +0000 (+0900) Subject: OF11: push_vlan support X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e34fbdd62bcd79dad4f62ba6ec920d8f3be71bb;p=openvswitch OF11: push_vlan support This implementes push_vlan with 802.1Q. NOTE: 802.1AD (QinQ) is not supported. It requires another effort. Signed-off-by: Isaku Yamahata Signed-off-by: Ben Pfaff --- diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index c6ba131a..170e796f 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -714,6 +714,15 @@ ofpact_from_openflow11(const union ofp_action *a, struct ofpbuf *out) ofpact_put_SET_VLAN_PCP(out)->vlan_pcp = a->vlan_pcp.vlan_pcp; break; + case OFPUTIL_OFPAT11_PUSH_VLAN: + if (((const struct ofp11_action_push *)a)->ethertype != + htons(ETH_TYPE_VLAN_8021Q)) { + /* TODO:XXX 802.1AD(QinQ) isn't supported at the moment */ + return OFPERR_OFPET_BAD_ACTION; + } + ofpact_put_PUSH_VLAN(out); + break; + case OFPUTIL_OFPAT11_POP_VLAN: ofpact_put_STRIP_VLAN(out); break; @@ -1065,6 +1074,7 @@ ofpact_check__(const struct ofpact *a, const struct flow *flow, int max_ports) case OFPACT_SET_VLAN_VID: case OFPACT_SET_VLAN_PCP: case OFPACT_STRIP_VLAN: + case OFPACT_PUSH_VLAN: case OFPACT_SET_ETH_SRC: case OFPACT_SET_ETH_DST: case OFPACT_SET_IPV4_SRC: @@ -1358,6 +1368,7 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf *out) case OFPACT_SET_VLAN_VID: case OFPACT_SET_VLAN_PCP: case OFPACT_STRIP_VLAN: + case OFPACT_PUSH_VLAN: case OFPACT_SET_ETH_SRC: case OFPACT_SET_ETH_DST: case OFPACT_SET_IPV4_SRC: @@ -1456,6 +1467,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct ofpbuf *out) = htons(ofpact_get_SET_L4_DST_PORT(a)->port); break; + case OFPACT_PUSH_VLAN: case OFPACT_CLEAR_ACTIONS: case OFPACT_GOTO_TABLE: /* TODO:XXX */ @@ -1548,6 +1560,12 @@ ofpact_to_openflow11(const struct ofpact *a, struct ofpbuf *out) ofputil_put_OFPAT11_POP_VLAN(out); break; + case OFPACT_PUSH_VLAN: + /* TODO:XXX ETH_TYPE_VLAN_8021AD case */ + ofputil_put_OFPAT11_PUSH_VLAN(out)->ethertype = + htons(ETH_TYPE_VLAN_8021Q); + break; + case OFPACT_SET_ETH_SRC: memcpy(ofputil_put_OFPAT11_SET_DL_SRC(out)->dl_addr, ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN); @@ -1711,6 +1729,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, uint16_t port) case OFPACT_SET_VLAN_VID: case OFPACT_SET_VLAN_PCP: case OFPACT_STRIP_VLAN: + case OFPACT_PUSH_VLAN: case OFPACT_SET_ETH_SRC: case OFPACT_SET_ETH_DST: case OFPACT_SET_IPV4_SRC: @@ -1894,6 +1913,11 @@ ofpact_format(const struct ofpact *a, struct ds *s) ds_put_cstr(s, "strip_vlan"); break; + case OFPACT_PUSH_VLAN: + /* TODO:XXX 802.1AD case*/ + ds_put_format(s, "push_vlan:%#"PRIx16, ETH_TYPE_VLAN_8021Q); + break; + case OFPACT_SET_ETH_SRC: ds_put_format(s, "mod_dl_src:"ETH_ADDR_FMT, ETH_ADDR_ARGS(ofpact_get_SET_ETH_SRC(a)->mac)); diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index 410103e8..b6cf4ba9 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -60,6 +60,7 @@ DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \ DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \ DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \ + DEFINE_OFPACT(PUSH_VLAN, ofpact_null, ofpact) \ DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \ DEFINE_OFPACT(SET_ETH_DST, ofpact_mac, ofpact) \ DEFINE_OFPACT(SET_IPV4_SRC, ofpact_ipv4, ofpact) \ diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 33065aa1..dedfb7e2 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -384,6 +384,7 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, { struct ofpact_tunnel *tunnel; uint16_t vid; + uint16_t ethertype; ovs_be32 ip; uint8_t pcp; uint8_t tos; @@ -424,6 +425,15 @@ parse_named_action(enum ofputil_action_code code, const struct flow *flow, ofpact_put_STRIP_VLAN(ofpacts); break; + case OFPUTIL_OFPAT11_PUSH_VLAN: + ethertype = str_to_u16(arg, "ethertype"); + if (ethertype != ETH_TYPE_VLAN_8021Q) { + /* TODO:XXXX ETH_TYPE_VLAN_8021AD case isn't supported */ + ovs_fatal(0, "%s: not a valid VLAN ethertype", arg); + } + ofpact_put_PUSH_VLAN(ofpacts); + break; + case OFPUTIL_OFPAT10_SET_DL_SRC: case OFPUTIL_OFPAT11_SET_DL_SRC: str_to_mac(arg, ofpact_put_SET_ETH_SRC(ofpacts)->mac); diff --git a/lib/ofp-util.def b/lib/ofp-util.def index 0b867c23..39575ba7 100644 --- a/lib/ofp-util.def +++ b/lib/ofp-util.def @@ -30,7 +30,7 @@ OFPAT11_ACTION(OFPAT11_SET_NW_TOS, ofp_action_nw_tos, 0, "mod_nw_tos") //OFPAT11_ACTION(OFPAT11_SET_NW_ECN, ofp11_action_nw_ecn, "0, mod_nw_ecn") OFPAT11_ACTION(OFPAT11_SET_TP_SRC, ofp_action_tp_port, 0, "mod_tp_src") OFPAT11_ACTION(OFPAT11_SET_TP_DST, ofp_action_tp_port, 0, "mod_tp_dst") -//OFPAT11_ACTION(OFPAT11_PUSH_VLAN, ofp11_action_push, 0, "push_vlan") +OFPAT11_ACTION(OFPAT11_PUSH_VLAN, ofp11_action_push, 0, "push_vlan") OFPAT11_ACTION(OFPAT11_POP_VLAN, ofp_action_header, 0, "pop_vlan") //OFPAT11_ACTION(OFPAT11_SET_QUEUE, ofp11_action_set_queue, 0, "set_queue") //OFPAT11_ACTION(OFPAT11_SET_NW_TTL, ofp11_action_nw_ttl, 0, "set_nw_ttl") diff --git a/lib/packets.h b/lib/packets.h index 24b51daf..e550be0b 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -177,7 +177,9 @@ void eth_addr_bitand(const uint8_t src[ETH_ADDR_LEN], #define ETH_TYPE_IP 0x0800 #define ETH_TYPE_ARP 0x0806 -#define ETH_TYPE_VLAN 0x8100 +#define ETH_TYPE_VLAN_8021Q 0x8100 +#define ETH_TYPE_VLAN ETH_TYPE_VLAN_8021Q +#define ETH_TYPE_VLAN_8021AD 0x88a8 #define ETH_TYPE_IPV6 0x86dd #define ETH_TYPE_LACP 0x8809 #define ETH_TYPE_RARP 0x8035 diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c8003863..fea4dac3 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -5500,6 +5500,11 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, ctx->flow.vlan_tci = htons(0); break; + case OFPACT_PUSH_VLAN: + /* TODO:XXX 802.1AD(QinQ) */ + ctx->flow.vlan_tci = htons(VLAN_CFI); + break; + case OFPACT_SET_ETH_SRC: memcpy(ctx->flow.dl_src, ofpact_get_SET_ETH_SRC(a)->mac, ETH_ADDR_LEN); diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at index 48758440..e232435e 100644 --- a/tests/ofp-actions.at +++ b/tests/ofp-actions.at @@ -169,6 +169,12 @@ AT_DATA([test-data], [dnl # actions=strip_vlan 0012 0008 00000000 +dnl 802.1ad isn't supported at the moment +dnl # actions=push_vlan:0x88a8 +dnl 0011 0008 88a8 0000 +# actions=push_vlan:0x8100 +0011 0008 8100 0000 + # actions=resubmit:5 ffff 0010 00002320 0001 0005 00000000 diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 8c175bad..9ea09737 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -897,6 +897,12 @@ as necessary to match the value specified. Valid values are between 0 .IP \fBstrip_vlan\fR Strips the VLAN tag from a packet if it is present. . +.IP \fBpush_vlan\fR:\fIethertype\fR +Push a new VLAN tag onto the packet. Ethertype is used as the the Ethertype +for the tag. Only ethertype 0x8100 should be used. (0x88a8 which the spec +allows isn't supported at the moment.) +A priority of zero and the tag of zero are used for the new tag. +. .IP \fBmod_dl_src\fB:\fImac\fR Sets the source Ethernet address to \fImac\fR. .