From dde49796980cda62a5787bd2d16ddf00dfbc82fd Mon Sep 17 00:00:00 2001 From: tyabe Date: Fri, 19 Jun 2009 18:58:58 -0700 Subject: [PATCH] Vlan pcp match: Implemented on datapath and udatapath --- datapath/datapath.c | 2 +- datapath/dp_act.c | 3 +++ datapath/flow.c | 10 +++++++--- datapath/flow.h | 7 +++++-- include/openflow/openflow.h | 12 +++++++----- lib/flow.c | 8 +++++--- lib/flow.h | 4 ++-- lib/ofp-print.c | 4 +++- lib/packets.h | 2 ++ udatapath/datapath.c | 2 +- udatapath/dp_act.c | 2 ++ udatapath/switch-flow.c | 6 ++++-- 12 files changed, 42 insertions(+), 20 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index b9523e8..e150bbe 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1512,7 +1512,7 @@ static int flow_stats_dump_callback(struct sw_flow *flow, void *private) ofs->match.nw_src = flow->key.nw_src; ofs->match.nw_dst = flow->key.nw_dst; ofs->match.nw_proto = flow->key.nw_proto; - ofs->match.pad = 0; + ofs->match.dl_vlan_pcp = flow->key.dl_vlan_pcp; ofs->match.tp_src = flow->key.tp_src; ofs->match.tp_dst = flow->key.tp_dst; diff --git a/datapath/dp_act.c b/datapath/dp_act.c index dcc93b9..63df0d8 100644 --- a/datapath/dp_act.c +++ b/datapath/dp_act.c @@ -18,6 +18,7 @@ #include "dp_act.h" #include "openflow/nicira-ext.h" #include "nx_act.h" +#include "flow.h" static uint16_t @@ -88,6 +89,8 @@ modify_vlan_tci(struct sk_buff *skb, struct sw_flow_key *key, vh = vlan_eth_hdr(skb); } key->dl_vlan = vh->h_vlan_TCI & htons(VLAN_VID_MASK); + key->dl_vlan_pcp = (uint8_t)((ntohs(vh->h_vlan_TCI) >> VLAN_PCP_SHIFT) + & VLAN_PCP_BITMASK); return skb; } diff --git a/datapath/flow.c b/datapath/flow.c index 97dd34c..4eea4cd 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -30,6 +30,7 @@ int flow_fields_match(const struct sw_flow_key *a, const struct sw_flow_key *b, { return ((w & OFPFW_IN_PORT || a->in_port == b->in_port) && (w & OFPFW_DL_VLAN || a->dl_vlan == b->dl_vlan) + && (w & OFPFW_DL_VLAN_PCP || a->dl_vlan_pcp == b->dl_vlan_pcp) && (w & OFPFW_DL_SRC || !memcmp(a->dl_src, b->dl_src, ETH_ALEN)) && (w & OFPFW_DL_DST || !memcmp(a->dl_dst, b->dl_dst, ETH_ALEN)) && (w & OFPFW_DL_TYPE || a->dl_type == b->dl_type) @@ -85,7 +86,7 @@ static uint32_t make_nw_mask(int n_wild_bits) void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) { to->wildcards = ntohl(from->wildcards) & OFPFW_ALL; - to->pad = 0; + to->dl_vlan_pcp = from->dl_vlan_pcp; to->in_port = from->in_port; to->dl_vlan = from->dl_vlan; memcpy(to->dl_src, from->dl_src, ETH_ALEN); @@ -146,7 +147,7 @@ void flow_fill_match(struct ofp_match* to, const struct sw_flow_key* from) to->nw_proto = from->nw_proto; to->tp_src = from->tp_src; to->tp_dst = from->tp_dst; - to->pad = 0; + to->dl_vlan_pcp = from->dl_vlan_pcp; } int flow_timeout(struct sw_flow *flow) @@ -311,10 +312,11 @@ EXPORT_SYMBOL(flow_replace_acts); /* Prints a representation of 'key' to the kernel log. */ void print_flow(const struct sw_flow_key *key) { - printk("wild%08x port%04x:vlan%04x mac%02x:%02x:%02x:%02x:%02x:%02x" + printk("wild%08x port%04x:vlan%04x vlan_pcp%02x mac%02x:%02x:%02x:%02x:%02x:%02x" "->%02x:%02x:%02x:%02x:%02x:%02x " "proto%04x ip%u.%u.%u.%u->%u.%u.%u.%u port%d->%d\n", key->wildcards, ntohs(key->in_port), ntohs(key->dl_vlan), + key->dl_vlan_pcp, key->dl_src[0], key->dl_src[1], key->dl_src[2], key->dl_src[3], key->dl_src[4], key->dl_src[5], key->dl_dst[0], key->dl_dst[1], key->dl_dst[2], @@ -394,6 +396,8 @@ int flow_extract(struct sk_buff *skb, uint16_t in_port, struct vlan_hdr *vh = (struct vlan_hdr*)(skb->data + nh_ofs); key->dl_type = vh->h_vlan_encapsulated_proto; key->dl_vlan = vh->h_vlan_TCI & htons(VLAN_VID_MASK); + key->dl_vlan_pcp = (uint8_t)((ntohs(vh->h_vlan_TCI) >> VLAN_PCP_SHIFT) + & VLAN_PCP_BITMASK); nh_ofs += sizeof(struct vlan_hdr); } memcpy(key->dl_src, eth->h_source, ETH_ALEN); diff --git a/datapath/flow.h b/datapath/flow.h index ce941b7..a8c0076 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -18,6 +18,9 @@ #include "openflow/openflow.h" +#define VLAN_PCP_SHIFT 13 +#define VLAN_PCP_BITMASK 0x0007 /* the least 3-bit is valid */ + struct sk_buff; struct ofp_flow_mod; @@ -32,14 +35,14 @@ struct sw_flow_key { uint32_t nw_src; /* IP source address. */ uint32_t nw_dst; /* IP destination address. */ uint16_t in_port; /* Input switch port */ - uint16_t dl_vlan; /* Input VLAN. */ + uint16_t dl_vlan; /* Input VLAN id. */ uint16_t dl_type; /* Ethernet frame type. */ uint16_t tp_src; /* TCP/UDP source port. */ uint16_t tp_dst; /* TCP/UDP destination port. */ uint8_t dl_src[ETH_ALEN]; /* Ethernet source address. */ uint8_t dl_dst[ETH_ALEN]; /* Ethernet destination address. */ uint8_t nw_proto; /* IP protocol. */ - uint8_t pad; /* Pad to 32-bit alignment. */ + uint8_t dl_vlan_pcp; /* Input VLAN priority. */ uint32_t wildcards; /* Wildcard fields (host byte order). */ uint32_t nw_src_mask; /* 1-bit in each significant nw_src bit. */ uint32_t nw_dst_mask; /* 1-bit in each significant nw_dst bit. */ diff --git a/include/openflow/openflow.h b/include/openflow/openflow.h index 7f44471..0ff6519 100644 --- a/include/openflow/openflow.h +++ b/include/openflow/openflow.h @@ -366,7 +366,7 @@ struct ofp_action_vlan_pcp { uint8_t vlan_pcp; /* VLAN priority. */ uint8_t pad[3]; }; -OFP_ASSERT(sizeof(struct ofp_action_vlan_vid) == 8); +OFP_ASSERT(sizeof(struct ofp_action_vlan_pcp) == 8); /* Action structure for OFPAT_SET_DL_SRC/DST. */ struct ofp_action_dl_addr { @@ -440,7 +440,7 @@ enum ofp_flow_mod_command { /* Flow wildcards. */ enum ofp_flow_wildcards { OFPFW_IN_PORT = 1 << 0, /* Switch input port. */ - OFPFW_DL_VLAN = 1 << 1, /* VLAN. */ + OFPFW_DL_VLAN = 1 << 1, /* VLAN id. */ OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */ OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */ OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */ @@ -463,8 +463,10 @@ enum ofp_flow_wildcards { OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT, OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT, + OFPFW_DL_VLAN_PCP = 1 << 20, /* VLAN priority. */ + /* Wildcard all fields. */ - OFPFW_ALL = ((1 << 20) - 1) + OFPFW_ALL = ((1 << 21) - 1) }; /* The wildcards for ICMP type and code fields use the transport source @@ -494,10 +496,10 @@ struct ofp_match { uint16_t in_port; /* Input switch port. */ uint8_t dl_src[OFP_ETH_ALEN]; /* Ethernet source address. */ uint8_t dl_dst[OFP_ETH_ALEN]; /* Ethernet destination address. */ - uint16_t dl_vlan; /* Input VLAN. */ + uint16_t dl_vlan; /* Input VLAN id. */ uint16_t dl_type; /* Ethernet frame type. */ uint8_t nw_proto; /* IP protocol. */ - uint8_t pad; /* Align to 32-bits. */ + uint8_t dl_vlan_pcp; /* Input VLAN priority. */ uint32_t nw_src; /* IP source address. */ uint32_t nw_dst; /* IP destination address. */ uint16_t tp_src; /* TCP/UDP source port. */ diff --git a/lib/flow.c b/lib/flow.c index 489540a..9f32a86 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -144,6 +144,8 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, struct flow *flow) if (vh) { flow->dl_type = vh->vlan_next_type; flow->dl_vlan = vh->vlan_tci & htons(VLAN_VID_MASK); + flow->dl_vlan_pcp = (uint8_t)((ntohs(vh->vlan_tci) >> VLAN_PCP_SHIFT) + & VLAN_PCP_BITMASK); } } memcpy(flow->dl_src, eth->eth_src, ETH_ADDR_LEN); @@ -216,16 +218,16 @@ flow_fill_match(struct ofp_match *to, const struct flow *from, to->nw_proto = from->nw_proto; to->tp_src = from->tp_src; to->tp_dst = from->tp_dst; - to->pad = 0; + to->dl_vlan_pcp = from->dl_vlan_pcp; } void flow_print(FILE *stream, const struct flow *flow) { fprintf(stream, - "port%04x:vlan%04x mac"ETH_ADDR_FMT"->"ETH_ADDR_FMT" " + "port%04x:vlan%04x vlan_pcp%02x mac"ETH_ADDR_FMT"->"ETH_ADDR_FMT" " "proto%04x ip"IP_FMT"->"IP_FMT" port%d->%d", - ntohs(flow->in_port), ntohs(flow->dl_vlan), + ntohs(flow->in_port), ntohs(flow->dl_vlan), flow->dl_vlan_pcp, ETH_ADDR_ARGS(flow->dl_src), ETH_ADDR_ARGS(flow->dl_dst), ntohs(flow->dl_type), IP_ARGS(&flow->nw_src), IP_ARGS(&flow->nw_dst), diff --git a/lib/flow.h b/lib/flow.h index 5c6c71d..03e13c0 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -50,14 +50,14 @@ struct flow { uint32_t nw_src; /* IP source address. */ uint32_t nw_dst; /* IP destination address. */ uint16_t in_port; /* Input switch port. */ - uint16_t dl_vlan; /* Input VLAN. */ + uint16_t dl_vlan; /* Input VLAN id. */ uint16_t dl_type; /* Ethernet frame type. */ uint16_t tp_src; /* TCP/UDP source port. */ uint16_t tp_dst; /* TCP/UDP destination port. */ uint8_t dl_src[6]; /* Ethernet source address. */ uint8_t dl_dst[6]; /* Ethernet destination address. */ uint8_t nw_proto; /* IP protocol. */ - uint8_t reserved; /* Pad to 32-bit alignment. */ + uint8_t dl_vlan_pcp; /* Input VLAN priority. */ }; BUILD_ASSERT_DECL(sizeof(struct flow) == 32); diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 4a6706e..b2abcac 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -160,7 +160,7 @@ ofp_packet_in(struct ds *string, const void *oh, size_t len, int verbosity) match.dl_vlan = flow.dl_vlan; match.dl_type = flow.dl_type; match.nw_proto = flow.nw_proto; - match.pad = 0; + match.dl_vlan_pcp = flow.dl_vlan_pcp; match.nw_src = flow.nw_src; match.nw_dst = flow.nw_dst; match.tp_src = flow.tp_src; @@ -682,6 +682,8 @@ ofp_match_to_string(const struct ofp_match *om, int verbosity) "%d", ntohs(om->in_port)); print_wild(&f, "dl_vlan=", w & OFPFW_DL_VLAN, verbosity, "0x%04x", ntohs(om->dl_vlan)); + print_wild(&f, "dl_vlan_pcp=", w & OFPFW_DL_VLAN_PCP, verbosity, + "0x%02x", om->dl_vlan_pcp); print_wild(&f, "dl_src=", w & OFPFW_DL_SRC, verbosity, ETH_ADDR_FMT, ETH_ADDR_ARGS(om->dl_src)); print_wild(&f, "dl_dst=", w & OFPFW_DL_DST, verbosity, diff --git a/lib/packets.h b/lib/packets.h index 7f6bd42..c451a1c 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -153,6 +153,8 @@ BUILD_ASSERT_DECL(LLC_SNAP_HEADER_LEN == sizeof(struct llc_snap_header)); #define VLAN_VID_MASK 0x0fff #define VLAN_PCP_MASK 0xe000 +#define VLAN_PCP_SHIFT 13 +#define VLAN_PCP_BITMASK 0x0007 /* the least 3-bit is valid */ #define VLAN_HEADER_LEN 4 struct vlan_header { diff --git a/udatapath/datapath.c b/udatapath/datapath.c index 5b94d37..ec77e3e 100644 --- a/udatapath/datapath.c +++ b/udatapath/datapath.c @@ -802,7 +802,7 @@ fill_flow_stats(struct ofpbuf *buffer, struct sw_flow *flow, ofs->match.nw_src = flow->key.flow.nw_src; ofs->match.nw_dst = flow->key.flow.nw_dst; ofs->match.nw_proto = flow->key.flow.nw_proto; - ofs->match.pad = 0; + ofs->match.dl_vlan_pcp = flow->key.flow.dl_vlan_pcp; ofs->match.tp_src = flow->key.flow.tp_src; ofs->match.tp_dst = flow->key.flow.tp_dst; ofs->duration = htonl((now - flow->created) / 1000); diff --git a/udatapath/dp_act.c b/udatapath/dp_act.c index b4d1751..beef81e 100644 --- a/udatapath/dp_act.c +++ b/udatapath/dp_act.c @@ -99,6 +99,8 @@ modify_vlan_tci(struct ofpbuf *buffer, struct sw_flow_key *key, } key->flow.dl_vlan = veh->veth_tci & htons(VLAN_VID_MASK); + key->flow.dl_vlan_pcp = (uint8_t)((ntohs(veh->veth_tci) >> VLAN_PCP_SHIFT) + & VLAN_PCP_BITMASK); } diff --git a/udatapath/switch-flow.c b/udatapath/switch-flow.c index 5bebe1a..5535f91 100644 --- a/udatapath/switch-flow.c +++ b/udatapath/switch-flow.c @@ -50,6 +50,7 @@ flow_fields_match(const struct flow *a, const struct flow *b, uint16_t w, { return ((w & OFPFW_IN_PORT || a->in_port == b->in_port) && (w & OFPFW_DL_VLAN || a->dl_vlan == b->dl_vlan) + && (w & OFPFW_DL_VLAN_PCP || a->dl_vlan_pcp == b->dl_vlan_pcp) && (w & OFPFW_DL_SRC || eth_addr_equals(a->dl_src, b->dl_src)) && (w & OFPFW_DL_DST || eth_addr_equals(a->dl_dst, b->dl_dst)) && (w & OFPFW_DL_TYPE || a->dl_type == b->dl_type) @@ -104,7 +105,7 @@ void flow_extract_match(struct sw_flow_key* to, const struct ofp_match* from) { to->wildcards = ntohl(from->wildcards) & OFPFW_ALL; - to->flow.reserved = 0; + to->flow.dl_vlan_pcp = from->dl_vlan_pcp; to->flow.in_port = from->in_port; to->flow.dl_vlan = from->dl_vlan; memcpy(to->flow.dl_src, from->dl_src, ETH_ADDR_LEN); @@ -232,10 +233,11 @@ void print_flow(const struct sw_flow_key *key) { const struct flow *f = &key->flow; - printf("wild%08x port%04x:vlan%04x mac%02x:%02x:%02x:%02x:%02x:%02x" + printf("wild%08x port%04x:vlan%04x vlan_pcp%02x mac%02x:%02x:%02x:%02x:%02x:%02x" "->%02x:%02x:%02x:%02x:%02x:%02x " "proto%04x ip%u.%u.%u.%u->%u.%u.%u.%u port%d->%d\n", key->wildcards, ntohs(f->in_port), ntohs(f->dl_vlan), + f->dl_vlan_pcp, f->dl_src[0], f->dl_src[1], f->dl_src[2], f->dl_src[3], f->dl_src[4], f->dl_src[5], f->dl_dst[0], f->dl_dst[1], f->dl_dst[2],