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
