[ovs-dev] [PATCH 1/2] datapath: Rearrange struct sw_flow_key to put IPv4/IPv6-specific details last.
Andrew Evans
aevans at nicira.com
Sat Mar 5 03:37:46 UTC 2011
IPv4/IPv6-specific fields are currently scattered about struct
sw_flow_table. Group them together in a union at the end to make it possible to
hash fewer bytes for IPv4 flows.
Suggested-by: Jesse Gross <jesse at nicira.com>
Signed-off-by: Andrew Evans <aevans at nicira.com>
---
datapath/flow.c | 170 +++++++++++++++++++++++++++++++------------------------
datapath/flow.h | 52 +++++++++++------
2 files changed, 130 insertions(+), 92 deletions(-)
diff --git a/datapath/flow.c b/datapath/flow.c
index fe05df3..e3a1a6d 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -118,8 +118,8 @@ static int parse_ipv6hdr(struct sk_buff *skb, struct sw_flow_key *key)
payload_ofs = (u8 *)(nh + 1) - skb->data;
payload_len = ntohs(nh->payload_len);
- memcpy(key->ipv6_src, nh->saddr.in6_u.u6_addr8, sizeof(key->ipv6_src));
- memcpy(key->ipv6_dst, nh->daddr.in6_u.u6_addr8, sizeof(key->ipv6_dst));
+ memcpy(key->ipv6.src, nh->saddr.in6_u.u6_addr8, sizeof(key->ipv6.src));
+ memcpy(key->ipv6.dst, nh->daddr.in6_u.u6_addr8, sizeof(key->ipv6.dst));
key->nw_tos = ipv6_get_dsfield(nh) & ~INET_ECN_MASK;
key->nw_proto = NEXTHDR_NONE;
@@ -326,8 +326,8 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
/* The ICMPv6 type and code fields use the 16-bit transport port
* fields, so we need to store them in 16-bit network byte order. */
- key->tp_src = htons(icmp->icmp6_type);
- key->tp_dst = htons(icmp->icmp6_code);
+ key->ipv6.tp.src = htons(icmp->icmp6_type);
+ key->ipv6.tp.dst = htons(icmp->icmp6_code);
if (!icmp->icmp6_code
&& ((icmp->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
@@ -343,7 +343,7 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
return -ENOMEM;
nd = (struct nd_msg *)skb_transport_header(skb);
- memcpy(key->nd_target, &nd->target, sizeof(key->nd_target));
+ memcpy(key->ipv6.nd_target, &nd->target, sizeof(key->ipv6.nd_target));
icmp_len -= sizeof(*nd);
offset = 0;
@@ -359,15 +359,15 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
* layer option is specified twice. */
if (nd_opt->nd_opt_type == ND_OPT_SOURCE_LL_ADDR
&& opt_len == 8) {
- if (!is_zero_ether_addr(key->arp_sha))
+ if (!is_zero_ether_addr(key->ipv6.nd_sha))
goto invalid;
- memcpy(key->arp_sha,
+ memcpy(key->ipv6.nd_sha,
&nd->opt[offset+sizeof(*nd_opt)], ETH_ALEN);
} else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LL_ADDR
&& opt_len == 8) {
- if (!is_zero_ether_addr(key->arp_tha))
+ if (!is_zero_ether_addr(key->ipv6.nd_tha))
goto invalid;
- memcpy(key->arp_tha,
+ memcpy(key->ipv6.nd_tha,
&nd->opt[offset+sizeof(*nd_opt)], ETH_ALEN);
}
@@ -379,9 +379,9 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
return 0;
invalid:
- memset(key->nd_target, 0, sizeof(key->nd_target));
- memset(key->arp_sha, 0, sizeof(key->arp_sha));
- memset(key->arp_tha, 0, sizeof(key->arp_tha));
+ memset(key->ipv6.nd_target, 0, sizeof(key->ipv6.nd_target));
+ memset(key->ipv6.nd_sha, 0, sizeof(key->ipv6.nd_sha));
+ memset(key->ipv6.nd_tha, 0, sizeof(key->ipv6.nd_tha));
return 0;
}
@@ -476,8 +476,8 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
}
nh = ip_hdr(skb);
- key->ipv4_src = nh->saddr;
- key->ipv4_dst = nh->daddr;
+ key->ipv4.src = nh->saddr;
+ key->ipv4.dst = nh->daddr;
key->nw_tos = nh->tos & ~INET_ECN_MASK;
key->nw_proto = nh->protocol;
@@ -487,14 +487,14 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
if (key->nw_proto == IPPROTO_TCP) {
if (tcphdr_ok(skb)) {
struct tcphdr *tcp = tcp_hdr(skb);
- key->tp_src = tcp->source;
- key->tp_dst = tcp->dest;
+ key->ipv4.tp.src = tcp->source;
+ key->ipv4.tp.dst = tcp->dest;
}
} else if (key->nw_proto == IPPROTO_UDP) {
if (udphdr_ok(skb)) {
struct udphdr *udp = udp_hdr(skb);
- key->tp_src = udp->source;
- key->tp_dst = udp->dest;
+ key->ipv4.tp.src = udp->source;
+ key->ipv4.tp.dst = udp->dest;
}
} else if (key->nw_proto == IPPROTO_ICMP) {
if (icmphdr_ok(skb)) {
@@ -502,8 +502,8 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
/* The ICMP type and code fields use the 16-bit
* transport port fields, so we need to store them
* in 16-bit network byte order. */
- key->tp_src = htons(icmp->type);
- key->tp_dst = htons(icmp->code);
+ key->ipv4.tp.src = htons(icmp->type);
+ key->ipv4.tp.dst = htons(icmp->code);
}
}
} else
@@ -525,10 +525,10 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
if (key->nw_proto == ARPOP_REQUEST
|| key->nw_proto == ARPOP_REPLY) {
- memcpy(&key->ipv4_src, arp->ar_sip, sizeof(key->ipv4_src));
- memcpy(&key->ipv4_dst, arp->ar_tip, sizeof(key->ipv4_dst));
- memcpy(key->arp_sha, arp->ar_sha, ETH_ALEN);
- memcpy(key->arp_tha, arp->ar_tha, ETH_ALEN);
+ memcpy(&key->ipv4.src, arp->ar_sip, sizeof(key->ipv4.src));
+ memcpy(&key->ipv4.dst, arp->ar_tip, sizeof(key->ipv4.dst));
+ memcpy(key->ipv4.arp.sha, arp->ar_sha, ETH_ALEN);
+ memcpy(key->ipv4.arp.tha, arp->ar_tha, ETH_ALEN);
}
}
} else if (key->dl_type == htons(ETH_P_IPV6)) {
@@ -547,14 +547,14 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
if (key->nw_proto == NEXTHDR_TCP) {
if (tcphdr_ok(skb)) {
struct tcphdr *tcp = tcp_hdr(skb);
- key->tp_src = tcp->source;
- key->tp_dst = tcp->dest;
+ key->ipv6.tp.src = tcp->source;
+ key->ipv6.tp.dst = tcp->dest;
}
} else if (key->nw_proto == NEXTHDR_UDP) {
if (udphdr_ok(skb)) {
struct udphdr *udp = udp_hdr(skb);
- key->tp_src = udp->source;
- key->tp_dst = udp->dest;
+ key->ipv6.tp.src = udp->source;
+ key->ipv6.tp.dst = udp->dest;
}
} else if (key->nw_proto == NEXTHDR_ICMP) {
if (icmp6hdr_ok(skb)) {
@@ -675,8 +675,8 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, const struct nlattr *attr)
if (swkey->dl_type != htons(ETH_P_IP))
return -EINVAL;
ipv4_key = nla_data(nla);
- swkey->ipv4_src = ipv4_key->ipv4_src;
- swkey->ipv4_dst = ipv4_key->ipv4_dst;
+ swkey->ipv4.src = ipv4_key->ipv4_src;
+ swkey->ipv4.dst = ipv4_key->ipv4_dst;
swkey->nw_proto = ipv4_key->ipv4_proto;
swkey->nw_tos = ipv4_key->ipv4_tos;
if (swkey->nw_tos & INET_ECN_MASK)
@@ -687,10 +687,10 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, const struct nlattr *attr)
if (swkey->dl_type != htons(ETH_P_IPV6))
return -EINVAL;
ipv6_key = nla_data(nla);
- memcpy(swkey->ipv6_src, ipv6_key->ipv6_src,
- sizeof(swkey->ipv6_src));
- memcpy(swkey->ipv6_dst, ipv6_key->ipv6_dst,
- sizeof(swkey->ipv6_dst));
+ memcpy(swkey->ipv6.src, ipv6_key->ipv6_src,
+ sizeof(swkey->ipv6.src));
+ memcpy(swkey->ipv6.dst, ipv6_key->ipv6_dst,
+ sizeof(swkey->ipv6.dst));
swkey->nw_proto = ipv6_key->ipv6_proto;
swkey->nw_tos = ipv6_key->ipv6_tos;
if (swkey->nw_tos & INET_ECN_MASK)
@@ -698,61 +698,75 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, const struct nlattr *attr)
break;
case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_TCP):
+ if (swkey->nw_proto != IPPROTO_TCP)
+ return -EINVAL;
+ tcp_key = nla_data(nla);
+ swkey->ipv4.tp.src = tcp_key->tcp_src;
+ swkey->ipv4.tp.dst = tcp_key->tcp_dst;
+ break;
+
case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_TCP):
if (swkey->nw_proto != IPPROTO_TCP)
return -EINVAL;
tcp_key = nla_data(nla);
- swkey->tp_src = tcp_key->tcp_src;
- swkey->tp_dst = tcp_key->tcp_dst;
+ swkey->ipv6.tp.src = tcp_key->tcp_src;
+ swkey->ipv6.tp.dst = tcp_key->tcp_dst;
break;
case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_UDP):
+ if (swkey->nw_proto != IPPROTO_UDP)
+ return -EINVAL;
+ udp_key = nla_data(nla);
+ swkey->ipv4.tp.src = udp_key->udp_src;
+ swkey->ipv4.tp.dst = udp_key->udp_dst;
+ break;
+
case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_UDP):
if (swkey->nw_proto != IPPROTO_UDP)
return -EINVAL;
udp_key = nla_data(nla);
- swkey->tp_src = udp_key->udp_src;
- swkey->tp_dst = udp_key->udp_dst;
+ swkey->ipv6.tp.src = udp_key->udp_src;
+ swkey->ipv6.tp.dst = udp_key->udp_dst;
break;
case TRANSITION(ODP_KEY_ATTR_IPV4, ODP_KEY_ATTR_ICMP):
if (swkey->nw_proto != IPPROTO_ICMP)
return -EINVAL;
icmp_key = nla_data(nla);
- swkey->tp_src = htons(icmp_key->icmp_type);
- swkey->tp_dst = htons(icmp_key->icmp_code);
+ swkey->ipv4.tp.src = htons(icmp_key->icmp_type);
+ swkey->ipv4.tp.dst = htons(icmp_key->icmp_code);
break;
case TRANSITION(ODP_KEY_ATTR_IPV6, ODP_KEY_ATTR_ICMPV6):
if (swkey->nw_proto != IPPROTO_ICMPV6)
return -EINVAL;
icmpv6_key = nla_data(nla);
- swkey->tp_src = htons(icmpv6_key->icmpv6_type);
- swkey->tp_dst = htons(icmpv6_key->icmpv6_code);
+ swkey->ipv6.tp.src = htons(icmpv6_key->icmpv6_type);
+ swkey->ipv6.tp.dst = htons(icmpv6_key->icmpv6_code);
break;
case TRANSITION(ODP_KEY_ATTR_ETHERTYPE, ODP_KEY_ATTR_ARP):
if (swkey->dl_type != htons(ETH_P_ARP))
return -EINVAL;
arp_key = nla_data(nla);
- swkey->ipv4_src = arp_key->arp_sip;
- swkey->ipv4_dst = arp_key->arp_tip;
+ swkey->ipv4.src = arp_key->arp_sip;
+ swkey->ipv4.dst = arp_key->arp_tip;
if (arp_key->arp_op & htons(0xff00))
return -EINVAL;
swkey->nw_proto = ntohs(arp_key->arp_op);
- memcpy(swkey->arp_sha, arp_key->arp_sha, ETH_ALEN);
- memcpy(swkey->arp_tha, arp_key->arp_tha, ETH_ALEN);
+ memcpy(swkey->ipv4.arp.sha, arp_key->arp_sha, ETH_ALEN);
+ memcpy(swkey->ipv4.arp.tha, arp_key->arp_tha, ETH_ALEN);
break;
case TRANSITION(ODP_KEY_ATTR_ICMPV6, ODP_KEY_ATTR_ND):
- if (swkey->tp_src != htons(NDISC_NEIGHBOUR_SOLICITATION)
- && swkey->tp_src != htons(NDISC_NEIGHBOUR_ADVERTISEMENT))
+ if (swkey->ipv6.tp.src != htons(NDISC_NEIGHBOUR_SOLICITATION)
+ && swkey->ipv6.tp.src != htons(NDISC_NEIGHBOUR_ADVERTISEMENT))
return -EINVAL;
nd_key = nla_data(nla);
- memcpy(swkey->nd_target, nd_key->nd_target,
- sizeof(swkey->nd_target));
- memcpy(swkey->arp_sha, nd_key->nd_sll, ETH_ALEN);
- memcpy(swkey->arp_tha, nd_key->nd_tll, ETH_ALEN);
+ memcpy(swkey->ipv6.nd_target, nd_key->nd_target,
+ sizeof(swkey->ipv6.nd_target));
+ memcpy(swkey->ipv6.nd_sha, nd_key->nd_sll, ETH_ALEN);
+ memcpy(swkey->ipv6.nd_tha, nd_key->nd_tll, ETH_ALEN);
break;
default:
@@ -797,8 +811,8 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, const struct nlattr *attr)
return 0;
case ODP_KEY_ATTR_ICMPV6:
- if (swkey->tp_src == htons(NDISC_NEIGHBOUR_SOLICITATION) ||
- swkey->tp_src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT))
+ if (swkey->ipv6.tp.src == htons(NDISC_NEIGHBOUR_SOLICITATION) ||
+ swkey->ipv6.tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT))
return -EINVAL;
return 0;
@@ -857,8 +871,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
goto nla_put_failure;
ipv4_key = nla_data(nla);
memset(ipv4_key, 0, sizeof(struct odp_key_ipv4));
- ipv4_key->ipv4_src = swkey->ipv4_src;
- ipv4_key->ipv4_dst = swkey->ipv4_dst;
+ ipv4_key->ipv4_src = swkey->ipv4.src;
+ ipv4_key->ipv4_dst = swkey->ipv4.dst;
ipv4_key->ipv4_proto = swkey->nw_proto;
ipv4_key->ipv4_tos = swkey->nw_tos;
} else if (swkey->dl_type == htons(ETH_P_IPV6)) {
@@ -869,9 +883,9 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
goto nla_put_failure;
ipv6_key = nla_data(nla);
memset(ipv6_key, 0, sizeof(struct odp_key_ipv6));
- memcpy(ipv6_key->ipv6_src, swkey->ipv6_src,
+ memcpy(ipv6_key->ipv6_src, swkey->ipv6.src,
sizeof(ipv6_key->ipv6_src));
- memcpy(ipv6_key->ipv6_dst, swkey->ipv6_dst,
+ memcpy(ipv6_key->ipv6_dst, swkey->ipv6.dst,
sizeof(ipv6_key->ipv6_dst));
ipv6_key->ipv6_proto = swkey->nw_proto;
ipv6_key->ipv6_tos = swkey->nw_tos;
@@ -883,11 +897,11 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
goto nla_put_failure;
arp_key = nla_data(nla);
memset(arp_key, 0, sizeof(struct odp_key_arp));
- arp_key->arp_sip = swkey->ipv4_src;
- arp_key->arp_tip = swkey->ipv4_dst;
+ arp_key->arp_sip = swkey->ipv4.src;
+ arp_key->arp_tip = swkey->ipv4.dst;
arp_key->arp_op = htons(swkey->nw_proto);
- memcpy(arp_key->arp_sha, swkey->arp_sha, ETH_ALEN);
- memcpy(arp_key->arp_tha, swkey->arp_tha, ETH_ALEN);
+ memcpy(arp_key->arp_sha, swkey->ipv4.arp.sha, ETH_ALEN);
+ memcpy(arp_key->arp_tha, swkey->ipv4.arp.tha, ETH_ALEN);
}
if (swkey->dl_type == htons(ETH_P_IP)
@@ -900,8 +914,13 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
tcp_key = nla_data(nla);
- tcp_key->tcp_src = swkey->tp_src;
- tcp_key->tcp_dst = swkey->tp_dst;
+ if (swkey->dl_type == htons(ETH_P_IP)) {
+ tcp_key->tcp_src = swkey->ipv4.tp.src;
+ tcp_key->tcp_dst = swkey->ipv4.tp.dst;
+ } else if (swkey->dl_type == htons(ETH_P_IPV6)) {
+ tcp_key->tcp_src = swkey->ipv6.tp.src;
+ tcp_key->tcp_dst = swkey->ipv6.tp.dst;
+ }
} else if (swkey->nw_proto == IPPROTO_UDP) {
struct odp_key_udp *udp_key;
@@ -909,8 +928,13 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
udp_key = nla_data(nla);
- udp_key->udp_src = swkey->tp_src;
- udp_key->udp_dst = swkey->tp_dst;
+ if (swkey->dl_type == htons(ETH_P_IP)) {
+ udp_key->udp_src = swkey->ipv4.tp.src;
+ udp_key->udp_dst = swkey->ipv4.tp.dst;
+ } else if (swkey->dl_type == htons(ETH_P_IPV6)) {
+ udp_key->udp_src = swkey->ipv6.tp.src;
+ udp_key->udp_dst = swkey->ipv6.tp.dst;
+ }
} else if (swkey->dl_type == htons(ETH_P_IP)
&& swkey->nw_proto == IPPROTO_ICMP) {
struct odp_key_icmp *icmp_key;
@@ -919,8 +943,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
icmp_key = nla_data(nla);
- icmp_key->icmp_type = ntohs(swkey->tp_src);
- icmp_key->icmp_code = ntohs(swkey->tp_dst);
+ icmp_key->icmp_type = ntohs(swkey->ipv4.tp.src);
+ icmp_key->icmp_code = ntohs(swkey->ipv4.tp.dst);
} else if (swkey->dl_type == htons(ETH_P_IPV6)
&& swkey->nw_proto == IPPROTO_ICMPV6) {
struct odp_key_icmpv6 *icmpv6_key;
@@ -929,8 +953,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
icmpv6_key = nla_data(nla);
- icmpv6_key->icmpv6_type = ntohs(swkey->tp_src);
- icmpv6_key->icmpv6_code = ntohs(swkey->tp_dst);
+ icmpv6_key->icmpv6_type = ntohs(swkey->ipv6.tp.src);
+ icmpv6_key->icmpv6_code = ntohs(swkey->ipv6.tp.dst);
if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION
|| icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
@@ -940,10 +964,10 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
if (!nla)
goto nla_put_failure;
nd_key = nla_data(nla);
- memcpy(nd_key->nd_target, swkey->nd_target,
+ memcpy(nd_key->nd_target, swkey->ipv6.nd_target,
sizeof(nd_key->nd_target));
- memcpy(nd_key->nd_sll, swkey->arp_sha, ETH_ALEN);
- memcpy(nd_key->nd_tll, swkey->arp_tha, ETH_ALEN);
+ memcpy(nd_key->nd_sll, swkey->ipv6.nd_sha, ETH_ALEN);
+ memcpy(nd_key->nd_tll, swkey->ipv6.nd_tha, ETH_ALEN);
}
}
}
diff --git a/datapath/flow.h b/datapath/flow.h
index a40073a..4b304d4 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -30,29 +30,43 @@ struct sw_flow_actions {
};
struct sw_flow_key {
- __be64 tun_id; /* Encapsulating tunnel ID. */
+ __be64 tun_id; /* Encapsulating tunnel ID. */
+ u16 in_port; /* Input switch port. */
+ __be16 dl_tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set
+ * otherwise. */
+ u8 dl_src[ETH_ALEN]; /* Ethernet source address. */
+ u8 dl_dst[ETH_ALEN]; /* Ethernet destination address. */
+ __be16 dl_type; /* Ethernet frame type. */
+ u8 nw_proto; /* IP protocol or lower 8 bits of
+ * ARP opcode. */
+ u8 nw_tos; /* IP ToS (DSCP field, 6 bits). */
union {
struct {
- __be32 ipv4_src; /* IPv4 source address. */
- __be32 ipv4_dst; /* IPv4 destination address. */
- };
+ __be32 src; /* IP source address. */
+ __be32 dst; /* IP destination address. */
+ union {
+ struct {
+ __be16 src; /* TCP/UDP source port. */
+ __be16 dst; /* TCP/UDP destination port. */
+ } tp;
+ struct {
+ u8 sha[ETH_ALEN]; /* ARP source hardware address. */
+ u8 tha[ETH_ALEN]; /* ARP target hardware address. */
+ } arp;
+ };
+ } ipv4;
struct {
- __be32 ipv6_src[4]; /* IPv6 source address. */
- __be32 ipv6_dst[4]; /* IPv6 source address. */
- };
+ __be32 src[4]; /* IPv6 source address. */
+ __be32 dst[4]; /* IPv6 destination address. */
+ struct {
+ __be16 src; /* TCP/UDP source port. */
+ __be16 dst; /* TCP/UDP destination port. */
+ } tp;
+ __be32 nd_target[4]; /* ND target address. */
+ u8 nd_sha[ETH_ALEN]; /* ND source hardware address. */
+ u8 nd_tha[ETH_ALEN]; /* ND target hardware address. */
+ } ipv6;
};
- __be32 nd_target[4]; /* IPv6 ND target address. */
- u16 in_port; /* Input switch port. */
- __be16 dl_tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set otherwise. */
- __be16 dl_type; /* Ethernet frame type. */
- __be16 tp_src; /* TCP/UDP source port. */
- __be16 tp_dst; /* TCP/UDP destination port. */
- u8 dl_src[ETH_ALEN]; /* Ethernet source address. */
- u8 dl_dst[ETH_ALEN]; /* Ethernet destination address. */
- u8 nw_proto; /* IP protocol or lower 8 bits of ARP opcode. */
- u8 nw_tos; /* IP ToS (DSCP field, 6 bits). */
- u8 arp_sha[ETH_ALEN]; /* ARP/ND source hardware address. */
- u8 arp_tha[ETH_ALEN]; /* ARP/ND target hardware address. */
};
struct sw_flow {
--
1.7.2.3
More information about the dev
mailing list