mirror of
https://github.com/openvswitch/ovs
synced 2025-10-27 15:18:06 +00:00
Widen TCP flags handling.
Widen TCP flags handling from 7 bits (uint8_t) to 12 bits (uint16_t). The kernel interface remains at 8 bits, which makes no functional difference now, as none of the higher bits is currently of interest to the userspace. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
committed by
Ben Pfaff
parent
1591fe8ee5
commit
a66733a8bc
@@ -676,8 +676,9 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (flow_stats.tcp_flags &&
|
||||
nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, flow_stats.tcp_flags))
|
||||
if ((u8)ntohs(flow_stats.tcp_flags) &&
|
||||
nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS,
|
||||
(u8)ntohs(flow_stats.tcp_flags)))
|
||||
goto nla_put_failure;
|
||||
|
||||
/* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if
|
||||
|
||||
@@ -60,20 +60,18 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies)
|
||||
return cur_ms - idle_ms;
|
||||
}
|
||||
|
||||
#define TCP_FLAGS_OFFSET 13
|
||||
#define TCP_FLAG_MASK 0x3f
|
||||
#define TCP_FLAGS_BE16(tp) (*(__be16 *)&tcp_flag_word(tp) & htons(0x0FFF))
|
||||
|
||||
void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
|
||||
{
|
||||
struct sw_flow_stats *stats = &flow->stats[smp_processor_id()];
|
||||
u8 tcp_flags = 0;
|
||||
__be16 tcp_flags = 0;
|
||||
|
||||
if ((flow->key.eth.type == htons(ETH_P_IP) ||
|
||||
flow->key.eth.type == htons(ETH_P_IPV6)) &&
|
||||
flow->key.ip.proto == IPPROTO_TCP &&
|
||||
likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) {
|
||||
u8 *tcp = (u8 *)tcp_hdr(skb);
|
||||
tcp_flags = *(tcp + TCP_FLAGS_OFFSET) & TCP_FLAG_MASK;
|
||||
tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb));
|
||||
}
|
||||
|
||||
spin_lock(&stats->lock);
|
||||
|
||||
@@ -152,7 +152,7 @@ struct sw_flow_stats {
|
||||
u64 byte_count; /* Number of bytes matched. */
|
||||
unsigned long used; /* Last used time (in jiffies). */
|
||||
spinlock_t lock; /* Lock for atomic stats update. */
|
||||
u8 tcp_flags; /* Union of seen TCP flags. */
|
||||
__be16 tcp_flags; /* Union of seen TCP flags. */
|
||||
} ____cacheline_aligned_in_smp;
|
||||
|
||||
struct sw_flow {
|
||||
|
||||
@@ -125,7 +125,7 @@ struct dp_netdev_flow {
|
||||
long long int used; /* Last used time, in monotonic msecs. */
|
||||
long long int packet_count; /* Number of packets matched. */
|
||||
long long int byte_count; /* Number of bytes matched. */
|
||||
uint8_t tcp_flags; /* Bitwise-OR of seen tcp_flags values. */
|
||||
uint16_t tcp_flags; /* Bitwise-OR of seen tcp_flags values. */
|
||||
|
||||
/* Actions. */
|
||||
struct nlattr *actions;
|
||||
|
||||
@@ -452,7 +452,7 @@ struct dpif_flow_stats {
|
||||
uint64_t n_packets;
|
||||
uint64_t n_bytes;
|
||||
long long int used;
|
||||
uint8_t tcp_flags;
|
||||
uint16_t tcp_flags;
|
||||
};
|
||||
|
||||
void dpif_flow_stats_extract(const struct flow *, const struct ofpbuf *packet,
|
||||
|
||||
@@ -898,7 +898,7 @@ packet_set_sctp_port(struct ofpbuf *packet, ovs_be16 src, ovs_be16 dst)
|
||||
*
|
||||
* 'flow' must be the flow corresponding to 'packet' and 'packet''s header
|
||||
* pointers must be properly initialized (e.g. with flow_extract()). */
|
||||
uint8_t
|
||||
uint16_t
|
||||
packet_get_tcp_flags(const struct ofpbuf *packet, const struct flow *flow)
|
||||
{
|
||||
if (dl_type_is_ip_any(flow->dl_type) &&
|
||||
@@ -914,7 +914,7 @@ packet_get_tcp_flags(const struct ofpbuf *packet, const struct flow *flow)
|
||||
* (e.g. obtained via packet_get_tcp_flags() or TCP_FLAGS) to 's', in the
|
||||
* format used by tcpdump. */
|
||||
void
|
||||
packet_format_tcp_flags(struct ds *s, uint8_t tcp_flags)
|
||||
packet_format_tcp_flags(struct ds *s, uint16_t tcp_flags)
|
||||
{
|
||||
if (!tcp_flags) {
|
||||
ds_put_cstr(s, "none");
|
||||
@@ -939,10 +939,22 @@ packet_format_tcp_flags(struct ds *s, uint8_t tcp_flags)
|
||||
if (tcp_flags & TCP_ACK) {
|
||||
ds_put_char(s, '.');
|
||||
}
|
||||
if (tcp_flags & 0x40) {
|
||||
ds_put_cstr(s, "[40]");
|
||||
if (tcp_flags & TCP_ECE) {
|
||||
ds_put_cstr(s, "E");
|
||||
}
|
||||
if (tcp_flags & 0x80) {
|
||||
ds_put_cstr(s, "[80]");
|
||||
if (tcp_flags & TCP_CWR) {
|
||||
ds_put_cstr(s, "C");
|
||||
}
|
||||
if (tcp_flags & TCP_NS) {
|
||||
ds_put_cstr(s, "N");
|
||||
}
|
||||
if (tcp_flags & 0x200) {
|
||||
ds_put_cstr(s, "[200]");
|
||||
}
|
||||
if (tcp_flags & 0x400) {
|
||||
ds_put_cstr(s, "[400]");
|
||||
}
|
||||
if (tcp_flags & 0x800) {
|
||||
ds_put_cstr(s, "[800]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,15 +487,18 @@ struct udp_header {
|
||||
};
|
||||
BUILD_ASSERT_DECL(UDP_HEADER_LEN == sizeof(struct udp_header));
|
||||
|
||||
#define TCP_FIN 0x01
|
||||
#define TCP_SYN 0x02
|
||||
#define TCP_RST 0x04
|
||||
#define TCP_PSH 0x08
|
||||
#define TCP_ACK 0x10
|
||||
#define TCP_URG 0x20
|
||||
#define TCP_FIN 0x001
|
||||
#define TCP_SYN 0x002
|
||||
#define TCP_RST 0x004
|
||||
#define TCP_PSH 0x008
|
||||
#define TCP_ACK 0x010
|
||||
#define TCP_URG 0x020
|
||||
#define TCP_ECE 0x040
|
||||
#define TCP_CWR 0x080
|
||||
#define TCP_NS 0x100
|
||||
|
||||
#define TCP_CTL(flags, offset) (htons((flags) | ((offset) << 12)))
|
||||
#define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x003f)
|
||||
#define TCP_FLAGS(tcp_ctl) (ntohs(tcp_ctl) & 0x0fff)
|
||||
#define TCP_OFFSET(tcp_ctl) (ntohs(tcp_ctl) >> 12)
|
||||
|
||||
#define TCP_HEADER_LEN 20
|
||||
@@ -641,7 +644,7 @@ void packet_set_tcp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
|
||||
void packet_set_udp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
|
||||
void packet_set_sctp_port(struct ofpbuf *, ovs_be16 src, ovs_be16 dst);
|
||||
|
||||
uint8_t packet_get_tcp_flags(const struct ofpbuf *, const struct flow *);
|
||||
void packet_format_tcp_flags(struct ds *, uint8_t);
|
||||
uint16_t packet_get_tcp_flags(const struct ofpbuf *, const struct flow *);
|
||||
void packet_format_tcp_flags(struct ds *, uint16_t);
|
||||
|
||||
#endif /* packets.h */
|
||||
|
||||
@@ -123,7 +123,7 @@ gen_netflow_rec(struct netflow *nf, struct netflow_flow *nf_flow,
|
||||
nf_rec->src_port = expired->flow.tp_src;
|
||||
nf_rec->dst_port = expired->flow.tp_dst;
|
||||
}
|
||||
nf_rec->tcp_flags = nf_flow->tcp_flags;
|
||||
nf_rec->tcp_flags = (uint8_t)nf_flow->tcp_flags;
|
||||
nf_rec->ip_proto = expired->flow.nw_proto;
|
||||
nf_rec->ip_tos = expired->flow.nw_tos & IP_DSCP_MASK;
|
||||
|
||||
@@ -302,7 +302,7 @@ netflow_flow_update_time(struct netflow *nf, struct netflow_flow *nf_flow,
|
||||
}
|
||||
|
||||
void
|
||||
netflow_flow_update_flags(struct netflow_flow *nf_flow, uint8_t tcp_flags)
|
||||
netflow_flow_update_flags(struct netflow_flow *nf_flow, uint16_t tcp_flags)
|
||||
{
|
||||
nf_flow->tcp_flags |= tcp_flags;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ struct netflow_flow {
|
||||
uint64_t byte_count_off; /* Byte count at last time out. */
|
||||
|
||||
ofp_port_t output_iface; /* Output interface index. */
|
||||
uint8_t tcp_flags; /* Bitwise-OR of all TCP flags seen. */
|
||||
uint16_t tcp_flags; /* Bitwise-OR of all TCP flags seen. */
|
||||
};
|
||||
|
||||
struct netflow *netflow_create(void);
|
||||
@@ -68,7 +68,7 @@ void netflow_flow_init(struct netflow_flow *);
|
||||
void netflow_flow_clear(struct netflow_flow *);
|
||||
void netflow_flow_update_time(struct netflow *, struct netflow_flow *,
|
||||
long long int used);
|
||||
void netflow_flow_update_flags(struct netflow_flow *, uint8_t tcp_flags);
|
||||
void netflow_flow_update_flags(struct netflow_flow *, uint16_t tcp_flags);
|
||||
bool netflow_active_timeout_expired(struct netflow *, struct netflow_flow *);
|
||||
|
||||
#endif /* netflow.h */
|
||||
|
||||
@@ -2543,7 +2543,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
|
||||
void
|
||||
xlate_in_init(struct xlate_in *xin, struct ofproto_dpif *ofproto,
|
||||
const struct flow *flow, struct rule_dpif *rule,
|
||||
uint8_t tcp_flags, const struct ofpbuf *packet)
|
||||
uint16_t tcp_flags, const struct ofpbuf *packet)
|
||||
{
|
||||
xin->ofproto = ofproto;
|
||||
xin->flow = *flow;
|
||||
|
||||
@@ -84,7 +84,7 @@ struct xlate_in {
|
||||
/* Union of the set of TCP flags seen so far in this flow. (Used only by
|
||||
* NXAST_FIN_TIMEOUT. Set to zero to avoid updating updating rules'
|
||||
* timeouts.) */
|
||||
uint8_t tcp_flags;
|
||||
uint16_t tcp_flags;
|
||||
|
||||
/* If nonnull, flow translation calls this function just before executing a
|
||||
* resubmit or OFPP_TABLE action. In addition, disables logging of traces
|
||||
@@ -152,7 +152,7 @@ void xlate_actions(struct xlate_in *, struct xlate_out *)
|
||||
OVS_EXCLUDED(xlate_rwlock);
|
||||
void xlate_in_init(struct xlate_in *, struct ofproto_dpif *,
|
||||
const struct flow *, struct rule_dpif *,
|
||||
uint8_t tcp_flags, const struct ofpbuf *packet);
|
||||
uint16_t tcp_flags, const struct ofpbuf *packet);
|
||||
void xlate_out_uninit(struct xlate_out *);
|
||||
void xlate_actions_for_side_effects(struct xlate_in *);
|
||||
void xlate_out_copy(struct xlate_out *dst, const struct xlate_out *src);
|
||||
|
||||
@@ -263,7 +263,7 @@ struct facet {
|
||||
/* Accounting. */
|
||||
uint64_t accounted_bytes; /* Bytes processed by facet_account(). */
|
||||
struct netflow_flow nf_flow; /* Per-flow NetFlow tracking data. */
|
||||
uint8_t tcp_flags; /* TCP flags seen for this 'rule'. */
|
||||
uint16_t tcp_flags; /* TCP flags seen for this 'rule'. */
|
||||
|
||||
struct xlate_out xout;
|
||||
|
||||
@@ -5282,7 +5282,7 @@ ofproto_trace(struct ofproto_dpif *ofproto, const struct flow *flow,
|
||||
struct ofpbuf odp_actions;
|
||||
struct trace_ctx trace;
|
||||
struct match match;
|
||||
uint8_t tcp_flags;
|
||||
uint16_t tcp_flags;
|
||||
|
||||
tcp_flags = packet ? packet_get_tcp_flags(packet, flow) : 0;
|
||||
trace.result = ds;
|
||||
|
||||
Reference in New Issue
Block a user