diff mbox

[ovs-dev,v2,11/15] tunnel: Add IP ECN related functions.

Message ID 1461290070-63896-12-git-send-email-pshelar@ovn.org
State Superseded
Headers show

Commit Message

Pravin Shelar April 22, 2016, 1:54 a.m. UTC
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(-)

Comments

Jesse Gross May 6, 2016, 10:37 p.m. UTC | #1
On Thu, Apr 21, 2016 at 6:54 PM, Pravin B Shelar <pshelar@ovn.org> wrote:
> 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>

Acked-by: Jesse Gross <jesse@kernel.org>
diff mbox

Patch

diff --git a/lib/packets.c b/lib/packets.c
index d0c0e68..13ba531 100644
--- a/lib/packets.c
+++ b/lib/packets.c
@@ -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;
+        }
+    }
+}
diff --git a/lib/packets.h b/lib/packets.h
index f1e29f8..8d627a5 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -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 */
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 18297b2..e65a2e4 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -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;