@@ -1388,3 +1388,24 @@ packet_csum_pseudoheader6(const struct ovs_16aligned_ip6_hdr *ip6)
return partial;
}
#endif
+
+void
+IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6)
+{
+ if (is_ipv6) {
+ ovs_16aligned_be32 *ip6 = dp_packet_l3(pkt);
+
+ put_16aligned_be32(ip6, get_16aligned_be32(ip6) |
+ htonl(IP_ECN_CE << 20));
+ } else {
+ struct ip_header *nh = dp_packet_l3(pkt);
+ uint8_t tos = nh->ip_tos;
+
+ tos |= IP_ECN_CE;
+ if (nh->ip_tos != tos) {
+ nh->ip_csum = recalc_csum16(nh->ip_csum, htons(nh->ip_tos),
+ htons((uint16_t) tos));
+ nh->ip_tos = tos;
+ }
+ }
+}
@@ -575,6 +575,12 @@ char *ip_parse_cidr_len(const char *s, int *n, ovs_be32 *ip,
#define IP_ECN_MASK 0x03
#define IP_DSCP_MASK 0xfc
+static inline int
+IP_ECN_is_ce(uint8_t dsfield)
+{
+ return (dsfield & IP_ECN_MASK) == IP_ECN_CE;
+}
+
#define IP_VERSION 4
#define IP_DONT_FRAGMENT 0x4000 /* Don't fragment. */
@@ -1057,5 +1063,6 @@ void compose_arp(struct dp_packet *, uint16_t arp_op,
void compose_nd(struct dp_packet *, const struct eth_addr eth_src,
struct in6_addr *, struct in6_addr *);
uint32_t packet_csum_pseudoheader(const struct ip_header *);
+void IP_ECN_set_ce(struct dp_packet *pkt, bool is_ipv6);
#endif /* packets.h */
@@ -342,7 +342,7 @@ tnl_process_ecn(struct flow *flow)
return true;
}
- if (is_ip_any(flow) && (flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) {
+ if (is_ip_any(flow) && IP_ECN_is_ce(flow->tunnel.ip_tos)) {
if ((flow->nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) {
VLOG_WARN_RL(&rl, "dropping tunnel packet marked ECN CE"
" but is not ECN capable");
@@ -382,7 +382,7 @@ tnl_wc_init(struct flow *flow, struct flow_wildcards *wc)
memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
if (is_ip_any(flow)
- && (flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) {
+ && IP_ECN_is_ce(flow->tunnel.ip_tos)) {
wc->masks.nw_tos |= IP_ECN_MASK;
}
}
@@ -455,7 +455,7 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
if (is_ip_any(flow)) {
wc->masks.nw_tos |= IP_ECN_MASK;
- if ((flow->nw_tos & IP_ECN_MASK) == IP_ECN_CE) {
+ if (IP_ECN_is_ce(flow->nw_tos)) {
flow->tunnel.ip_tos |= IP_ECN_ECT_0;
} else {
flow->tunnel.ip_tos |= flow->nw_tos & IP_ECN_MASK;
Set and get functions for IP explicit congestion notification flag. These function would be used by STT reassembly code. Signed-off-by: Pravin B Shelar <pshelar@ovn.org> --- lib/packets.c | 21 +++++++++++++++++++++ lib/packets.h | 7 +++++++ ofproto/tunnel.c | 6 +++--- 3 files changed, 31 insertions(+), 3 deletions(-)