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 <[email protected]>
---
 ofproto/ofproto-dpif-sflow.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

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:
-- 
1.8.3.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to