diff mbox

[ovs-dev,RFC,2/2] sflow: export extended NAT data

Message ID 1503578037-47587-2-git-send-email-michalx.weglicki@intel.com
State Deferred
Headers show

Commit Message

Weglicki, MichalX Aug. 24, 2017, 12:33 p.m. UTC
With addition of sFlow output sampling, it is possible to export additional
data, which isn't available during input sampling. This patch introduces
support for exporting extend NAT data.

Signed-off-by: Przemyslaw Szczerbik <przemyslawx.szczerbik@intel.com>
---
 ofproto/ofproto-dpif-sflow.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
diff mbox

Patch

diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
index b92f681..bd02bdd 100644
--- a/ofproto/ofproto-dpif-sflow.c
+++ b/ofproto/ofproto-dpif-sflow.c
@@ -878,6 +878,31 @@  dpif_sflow_tunnel_v4(uint8_t tunnel_ipproto,
     ipv4->dst_port = (OVS_FORCE uint16_t) tunnel->tp_dst;
 }
 
+static int
+dpif_sflow_ex_nat(const struct flow *flow, SFLExtended_nat *nat)
+
+{
+    int ret = 0;
+    uint16_t dl_type = ntohs(flow->dl_type);
+
+    if (dl_type == ETH_TYPE_IP) {
+        nat->src.type = SFLADDRESSTYPE_IP_V4;
+        nat->dst.type = SFLADDRESSTYPE_IP_V4;
+        nat->src.address.ip_v4.addr = flow->ct_nw_src;
+        nat->dst.address.ip_v4.addr = flow->ct_nw_dst;
+    } else if (dl_type == ETH_TYPE_IPV6) {
+        nat->src.type = SFLADDRESSTYPE_IP_V6;
+        nat->dst.type = SFLADDRESSTYPE_IP_V6;
+        memcpy(nat->src.address.ip_v6.addr, flow->ct_ipv6_src.s6_addr, 16);
+        memcpy(nat->dst.address.ip_v6.addr, flow->ct_ipv6_dst.s6_addr, 16);
+    } else {
+        /*XXX: Do we need to handle other cases? */
+        ret = -1;
+    }
+
+    return ret;
+}
+
 static void
 dpif_sflow_push_mpls_lse(struct dpif_sflow_actions *sflow_actions,
                          ovs_be32 lse)
@@ -1285,6 +1310,7 @@  dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
     SFLFlow_sample_element hdrElem;
     SFLSampled_header *header;
     SFLFlow_sample_element switchElem;
+    SFLFlow_sample_element natElem;
     uint8_t tnlInProto, tnlOutProto;
     SFLFlow_sample_element tnlInElem, tnlOutElem;
     SFLFlow_sample_element vniInElem, vniOutElem;
@@ -1343,6 +1369,14 @@  dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
 
     fs.output = cookie->sflow.output;
 
+    /* Add extended NAT element if src or dst address was mangled by NAT */
+    bool add_ex_nat = flow->ct_state & OVS_CS_F_NAT_MASK;
+    if (add_ex_nat) {
+        memset(&natElem, 0, sizeof(natElem));
+        natElem.tag = SFLFLOW_EX_NAT;
+        add_ex_nat = !dpif_sflow_ex_nat(flow, &natElem.flowType.nat);
+    }
+
     /* Input tunnel. */
     if (flow->tunnel.ip_dst) {
 	memset(&tnlInElem, 0, sizeof(tnlInElem));
@@ -1407,6 +1441,9 @@  dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
     /* Submit the flow sample to be encoded into the next datagram. */
     SFLADD_ELEMENT(&fs, &hdrElem);
     SFLADD_ELEMENT(&fs, &switchElem);
+    if (add_ex_nat) {
+        SFLADD_ELEMENT(&fs, &natElem);
+    }
     sfl_sampler_writeFlowSample(sampler, &fs);
 
 out: